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 int xmon_core(struct pt_regs
*regs
, int fromipi
)
342 long recurse_jmp
[JMP_BUF_LEN
];
343 unsigned long offset
;
348 unsigned long timeout
;
351 local_irq_save(flags
);
353 bp
= in_breakpoint_table(regs
->nip
, &offset
);
355 regs
->nip
= bp
->address
+ offset
;
356 atomic_dec(&bp
->ref_count
);
362 cpu
= smp_processor_id();
363 if (cpu_isset(cpu
, cpus_in_xmon
)) {
366 printf("cpu 0x%x: Exception %lx %s in xmon, "
367 "returning to main loop\n",
368 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
369 release_output_lock();
370 longjmp(xmon_fault_jmp
[cpu
], 1);
373 if (setjmp(recurse_jmp
) != 0) {
374 if (!in_xmon
|| !xmon_gate
) {
376 printf("xmon: WARNING: bad recursive fault "
377 "on cpu 0x%x\n", cpu
);
378 release_output_lock();
381 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
385 xmon_fault_jmp
[cpu
] = recurse_jmp
;
386 cpu_set(cpu
, cpus_in_xmon
);
389 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
))
390 bp
= at_breakpoint(regs
->nip
);
391 if (bp
|| (regs
->msr
& MSR_RI
) == 0)
398 printf("cpu 0x%x stopped at breakpoint 0x%x (",
400 xmon_print_symbol(regs
->nip
, " ", ")\n");
402 if ((regs
->msr
& MSR_RI
) == 0)
403 printf("WARNING: exception is not recoverable, "
405 release_output_lock();
410 while (secondary
&& !xmon_gate
) {
414 secondary
= test_and_set_bit(0, &in_xmon
);
419 if (!secondary
&& !xmon_gate
) {
420 /* we are the first cpu to come in */
421 /* interrupt other cpu(s) */
422 int ncpus
= num_online_cpus();
427 smp_send_debugger_break(MSG_ALL_BUT_SELF
);
428 /* wait for other cpus to come in */
429 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
430 if (cpus_weight(cpus_in_xmon
) >= ncpus
)
436 disable_surveillance();
437 /* for breakpoint or single step, print the current instr. */
438 if (bp
|| TRAP(regs
) == 0xd00)
439 ppc_inst_dump(regs
->nip
, 1, 0);
440 printf("enter ? for help\n");
449 if (cpu
== xmon_owner
) {
450 if (!test_and_set_bit(0, &xmon_taken
)) {
455 while (cpu
== xmon_owner
)
469 /* have switched to some other cpu */
474 cpu_clear(cpu
, cpus_in_xmon
);
475 xmon_fault_jmp
[cpu
] = NULL
;
477 /* UP is simple... */
479 printf("Exception %lx %s in xmon, returning to main loop\n",
480 regs
->trap
, getvecname(TRAP(regs
)));
481 longjmp(xmon_fault_jmp
[0], 1);
483 if (setjmp(recurse_jmp
) == 0) {
484 xmon_fault_jmp
[0] = recurse_jmp
;
488 bp
= at_breakpoint(regs
->nip
);
490 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
491 xmon_print_symbol(regs
->nip
, " ", ")\n");
493 if ((regs
->msr
& MSR_RI
) == 0)
494 printf("WARNING: exception is not recoverable, "
497 disable_surveillance();
498 /* for breakpoint or single step, print the current instr. */
499 if (bp
|| TRAP(regs
) == 0xd00)
500 ppc_inst_dump(regs
->nip
, 1, 0);
501 printf("enter ? for help\n");
510 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
511 bp
= at_breakpoint(regs
->nip
);
513 int stepped
= emulate_step(regs
, bp
->instr
[0]);
515 regs
->nip
= (unsigned long) &bp
->instr
[0];
516 atomic_inc(&bp
->ref_count
);
517 } else if (stepped
< 0) {
518 printf("Couldn't single-step %s instruction\n",
519 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
526 local_irq_restore(flags
);
528 return cmd
!= 'X' && cmd
!= EOF
;
531 int xmon(struct pt_regs
*excp
)
536 ppc_save_regs(®s
);
540 return xmon_core(excp
, 0);
544 irqreturn_t
xmon_irq(int irq
, void *d
)
547 local_irq_save(flags
);
548 printf("Keyboard interrupt\n");
549 xmon(get_irq_regs());
550 local_irq_restore(flags
);
554 static int xmon_bpt(struct pt_regs
*regs
)
557 unsigned long offset
;
559 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
562 /* Are we at the trap at bp->instr[1] for some bp? */
563 bp
= in_breakpoint_table(regs
->nip
, &offset
);
564 if (bp
!= NULL
&& offset
== 4) {
565 regs
->nip
= bp
->address
+ 4;
566 atomic_dec(&bp
->ref_count
);
570 /* Are we at a breakpoint? */
571 bp
= at_breakpoint(regs
->nip
);
580 static int xmon_sstep(struct pt_regs
*regs
)
588 static int xmon_dabr_match(struct pt_regs
*regs
)
590 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
592 if (dabr
.enabled
== 0)
598 static int xmon_iabr_match(struct pt_regs
*regs
)
600 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
608 static int xmon_ipi(struct pt_regs
*regs
)
611 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
617 static int xmon_fault_handler(struct pt_regs
*regs
)
620 unsigned long offset
;
622 if (in_xmon
&& catch_memory_errors
)
623 handle_fault(regs
); /* doesn't return */
625 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
626 bp
= in_breakpoint_table(regs
->nip
, &offset
);
628 regs
->nip
= bp
->address
+ offset
;
629 atomic_dec(&bp
->ref_count
);
636 static struct bpt
*at_breakpoint(unsigned long pc
)
642 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
643 if (bp
->enabled
&& pc
== bp
->address
)
648 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
652 off
= nip
- (unsigned long) bpts
;
653 if (off
>= sizeof(bpts
))
655 off
%= sizeof(struct bpt
);
656 if (off
!= offsetof(struct bpt
, instr
[0])
657 && off
!= offsetof(struct bpt
, instr
[1]))
659 *offp
= off
- offsetof(struct bpt
, instr
[0]);
660 return (struct bpt
*) (nip
- off
);
663 static struct bpt
*new_breakpoint(unsigned long a
)
668 bp
= at_breakpoint(a
);
672 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
673 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
675 bp
->instr
[1] = bpinstr
;
676 store_inst(&bp
->instr
[1]);
681 printf("Sorry, no free breakpoints. Please clear one first.\n");
685 static void insert_bpts(void)
691 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
692 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
694 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
695 printf("Couldn't read instruction at %lx, "
696 "disabling breakpoint there\n", bp
->address
);
700 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
701 printf("Breakpoint at %lx is on an mtmsrd or rfid "
702 "instruction, disabling it\n", bp
->address
);
706 store_inst(&bp
->instr
[0]);
707 if (bp
->enabled
& BP_IABR
)
709 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
710 printf("Couldn't write instruction at %lx, "
711 "disabling breakpoint there\n", bp
->address
);
712 bp
->enabled
&= ~BP_TRAP
;
715 store_inst((void *)bp
->address
);
719 static void insert_cpu_bpts(void)
722 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
723 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
724 mtspr(SPRN_IABR
, iabr
->address
725 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
728 static void remove_bpts(void)
735 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
736 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
738 if (mread(bp
->address
, &instr
, 4) == 4
740 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
741 printf("Couldn't remove breakpoint at %lx\n",
744 store_inst((void *)bp
->address
);
748 static void remove_cpu_bpts(void)
751 if (cpu_has_feature(CPU_FTR_IABR
))
755 /* Command interpreting routine */
756 static char *last_cmd
;
759 cmds(struct pt_regs
*excp
)
766 if (!xmon_no_auto_backtrace
) {
767 xmon_no_auto_backtrace
= 1;
768 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
773 printf("%x:", smp_processor_id());
774 #endif /* CONFIG_SMP */
780 if (last_cmd
== NULL
)
782 take_input(last_cmd
);
816 prregs(excp
); /* print regs */
831 if (do_spu_cmd() == 0)
840 printf(" <no input ...>\n");
844 xmon_puts(help_string
);
862 #ifdef CONFIG_PPC_STD_MMU
873 printf("Unrecognized command: ");
875 if (' ' < cmd
&& cmd
<= '~')
878 printf("\\x%x", cmd
);
880 } while (cmd
!= '\n');
881 printf(" (type ? for help)\n");
888 * Step a single instruction.
889 * Some instructions we emulate, others we execute with MSR_SE set.
891 static int do_step(struct pt_regs
*regs
)
896 /* check we are in 64-bit kernel mode, translation enabled */
897 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
898 if (mread(regs
->nip
, &instr
, 4) == 4) {
899 stepped
= emulate_step(regs
, instr
);
901 printf("Couldn't single-step %s instruction\n",
902 (IS_RFID(instr
)? "rfid": "mtmsrd"));
906 regs
->trap
= 0xd00 | (regs
->trap
& 1);
907 printf("stepped to ");
908 xmon_print_symbol(regs
->nip
, " ", "\n");
909 ppc_inst_dump(regs
->nip
, 1, 0);
918 static void bootcmds(void)
924 ppc_md
.restart(NULL
);
931 static int cpu_cmd(void)
938 if (!scanhex(&cpu
)) {
939 /* print cpus waiting or in xmon */
940 printf("cpus stopped:");
942 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
943 if (cpu_isset(cpu
, cpus_in_xmon
)) {
949 printf("-%x", cpu
- 1);
954 printf("-%x", NR_CPUS
- 1);
958 /* try to switch to cpu specified */
959 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
960 printf("cpu 0x%x isn't in xmon\n", cpu
);
967 while (!xmon_taken
) {
968 if (--timeout
== 0) {
969 if (test_and_set_bit(0, &xmon_taken
))
971 /* take control back */
973 xmon_owner
= smp_processor_id();
974 printf("cpu %u didn't take control\n", cpu
);
982 #endif /* CONFIG_SMP */
985 static unsigned short fcstab
[256] = {
986 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
987 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
988 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
989 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
990 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
991 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
992 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
993 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
994 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
995 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
996 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
997 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
998 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
999 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1000 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1001 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1002 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1003 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1004 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1005 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1006 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1007 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1008 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1009 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1010 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1011 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1012 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1013 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1014 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1015 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1016 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1017 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1020 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1029 if (!scanhex(&adrs
))
1031 if (!scanhex(&ncsum
))
1034 for (i
= 0; i
< ncsum
; ++i
) {
1035 if (mread(adrs
+i
, &v
, 1) == 0) {
1036 printf("csum stopped at %x\n", adrs
+i
);
1041 printf("%x\n", fcs
);
1045 * Check if this is a suitable place to put a breakpoint.
1047 static long check_bp_loc(unsigned long addr
)
1052 if (!is_kernel_addr(addr
)) {
1053 printf("Breakpoints may only be placed at kernel addresses\n");
1056 if (!mread(addr
, &instr
, sizeof(instr
))) {
1057 printf("Can't read instruction at address %lx\n", addr
);
1060 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1061 printf("Breakpoints may not be placed on mtmsrd or rfid "
1068 static char *breakpoint_help_string
=
1069 "Breakpoint command usage:\n"
1070 "b show breakpoints\n"
1071 "b <addr> [cnt] set breakpoint at given instr addr\n"
1072 "bc clear all breakpoints\n"
1073 "bc <n/addr> clear breakpoint number n or at addr\n"
1074 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1075 "bd <addr> [cnt] set hardware data breakpoint\n"
1085 const char badaddr
[] = "Only kernel addresses are permitted "
1086 "for breakpoints\n";
1091 case 'd': /* bd - hardware data breakpoint */
1096 else if (cmd
== 'w')
1102 if (scanhex(&dabr
.address
)) {
1103 if (!is_kernel_addr(dabr
.address
)) {
1108 dabr
.enabled
= mode
| BP_DABR
;
1112 case 'i': /* bi - hardware instr breakpoint */
1113 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1114 printf("Hardware instruction breakpoint "
1115 "not supported on this cpu\n");
1119 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1124 if (!check_bp_loc(a
))
1126 bp
= new_breakpoint(a
);
1128 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1136 /* clear all breakpoints */
1137 for (i
= 0; i
< NBPTS
; ++i
)
1138 bpts
[i
].enabled
= 0;
1141 printf("All breakpoints cleared\n");
1145 if (a
<= NBPTS
&& a
>= 1) {
1146 /* assume a breakpoint number */
1147 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1149 /* assume a breakpoint address */
1150 bp
= at_breakpoint(a
);
1152 printf("No breakpoint at %x\n", a
);
1157 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1158 xmon_print_symbol(bp
->address
, " ", ")\n");
1166 printf(breakpoint_help_string
);
1171 /* print all breakpoints */
1172 printf(" type address\n");
1174 printf(" data "REG
" [", dabr
.address
);
1175 if (dabr
.enabled
& 1)
1177 if (dabr
.enabled
& 2)
1181 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1184 printf("%2x %s ", BP_NUM(bp
),
1185 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1186 xmon_print_symbol(bp
->address
, " ", "\n");
1191 if (!check_bp_loc(a
))
1193 bp
= new_breakpoint(a
);
1195 bp
->enabled
|= BP_TRAP
;
1200 /* Very cheap human name for vector lookup. */
1202 const char *getvecname(unsigned long vec
)
1207 case 0x100: ret
= "(System Reset)"; break;
1208 case 0x200: ret
= "(Machine Check)"; break;
1209 case 0x300: ret
= "(Data Access)"; break;
1210 case 0x380: ret
= "(Data SLB Access)"; break;
1211 case 0x400: ret
= "(Instruction Access)"; break;
1212 case 0x480: ret
= "(Instruction SLB Access)"; break;
1213 case 0x500: ret
= "(Hardware Interrupt)"; break;
1214 case 0x600: ret
= "(Alignment)"; break;
1215 case 0x700: ret
= "(Program Check)"; break;
1216 case 0x800: ret
= "(FPU Unavailable)"; break;
1217 case 0x900: ret
= "(Decrementer)"; break;
1218 case 0xc00: ret
= "(System Call)"; break;
1219 case 0xd00: ret
= "(Single Step)"; break;
1220 case 0xf00: ret
= "(Performance Monitor)"; break;
1221 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1222 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1228 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1229 unsigned long *endp
)
1231 unsigned long size
, offset
;
1234 *startp
= *endp
= 0;
1237 if (setjmp(bus_error_jmp
) == 0) {
1238 catch_memory_errors
= 1;
1240 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1242 *startp
= pc
- offset
;
1243 *endp
= pc
- offset
+ size
;
1247 catch_memory_errors
= 0;
1250 static int xmon_depth_to_print
= 64;
1252 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1253 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1255 #ifdef __powerpc64__
1256 #define REGS_OFFSET 0x70
1258 #define REGS_OFFSET 16
1261 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1265 unsigned long newsp
;
1266 unsigned long marker
;
1268 struct pt_regs regs
;
1271 if (sp
< PAGE_OFFSET
) {
1273 printf("SP (%lx) is in userspace\n", sp
);
1277 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1278 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1279 printf("Couldn't read stack frame at %lx\n", sp
);
1284 * For the first stack frame, try to work out if
1285 * LR and/or the saved LR value in the bottommost
1286 * stack frame are valid.
1288 if ((pc
| lr
) != 0) {
1289 unsigned long fnstart
, fnend
;
1290 unsigned long nextip
;
1293 get_function_bounds(pc
, &fnstart
, &fnend
);
1296 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1297 sizeof(unsigned long));
1299 if (lr
< PAGE_OFFSET
1300 || (fnstart
<= lr
&& lr
< fnend
))
1302 } else if (lr
== nextip
) {
1304 } else if (lr
>= PAGE_OFFSET
1305 && !(fnstart
<= lr
&& lr
< fnend
)) {
1306 printf("[link register ] ");
1307 xmon_print_symbol(lr
, " ", "\n");
1310 printf("["REG
"] ", sp
);
1311 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1316 printf("["REG
"] ", sp
);
1317 xmon_print_symbol(ip
, " ", "\n");
1320 /* Look for "regshere" marker to see if this is
1321 an exception frame. */
1322 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1323 && marker
== STACK_FRAME_REGS_MARKER
) {
1324 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1326 printf("Couldn't read registers at %lx\n",
1330 printf("--- Exception: %lx %s at ", regs
.trap
,
1331 getvecname(TRAP(®s
)));
1334 xmon_print_symbol(pc
, " ", "\n");
1341 } while (count
++ < xmon_depth_to_print
);
1344 static void backtrace(struct pt_regs
*excp
)
1349 xmon_show_stack(sp
, 0, 0);
1351 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1355 static void print_bug_trap(struct pt_regs
*regs
)
1358 const struct bug_entry
*bug
;
1361 if (regs
->msr
& MSR_PR
)
1362 return; /* not in kernel */
1363 addr
= regs
->nip
; /* address of trap instruction */
1364 if (addr
< PAGE_OFFSET
)
1366 bug
= find_bug(regs
->nip
);
1369 if (is_warning_bug(bug
))
1372 #ifdef CONFIG_DEBUG_BUGVERBOSE
1373 printf("kernel BUG at %s:%u!\n",
1374 bug
->file
, bug
->line
);
1376 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1378 #endif /* CONFIG_BUG */
1381 static void excprint(struct pt_regs
*fp
)
1386 printf("cpu 0x%x: ", smp_processor_id());
1387 #endif /* CONFIG_SMP */
1390 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1392 xmon_print_symbol(fp
->nip
, ": ", "\n");
1394 printf(" lr: ", fp
->link
);
1395 xmon_print_symbol(fp
->link
, ": ", "\n");
1397 printf(" sp: %lx\n", fp
->gpr
[1]);
1398 printf(" msr: %lx\n", fp
->msr
);
1400 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1401 printf(" dar: %lx\n", fp
->dar
);
1403 printf(" dsisr: %lx\n", fp
->dsisr
);
1406 printf(" current = 0x%lx\n", current
);
1408 printf(" paca = 0x%lx\n", get_paca());
1411 printf(" pid = %ld, comm = %s\n",
1412 current
->pid
, current
->comm
);
1419 static void prregs(struct pt_regs
*fp
)
1423 struct pt_regs regs
;
1425 if (scanhex(&base
)) {
1426 if (setjmp(bus_error_jmp
) == 0) {
1427 catch_memory_errors
= 1;
1429 regs
= *(struct pt_regs
*)base
;
1433 catch_memory_errors
= 0;
1434 printf("*** Error reading registers from "REG
"\n",
1438 catch_memory_errors
= 0;
1443 if (FULL_REGS(fp
)) {
1444 for (n
= 0; n
< 16; ++n
)
1445 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1446 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1448 for (n
= 0; n
< 7; ++n
)
1449 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1450 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1453 for (n
= 0; n
< 32; ++n
) {
1454 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1455 (n
& 3) == 3? "\n": " ");
1456 if (n
== 12 && !FULL_REGS(fp
)) {
1463 xmon_print_symbol(fp
->nip
, " ", "\n");
1465 xmon_print_symbol(fp
->link
, " ", "\n");
1466 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1467 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1468 fp
->ctr
, fp
->xer
, fp
->trap
);
1470 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1471 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1474 static void cacheflush(void)
1477 unsigned long nflush
;
1482 scanhex((void *)&adrs
);
1487 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1488 if (setjmp(bus_error_jmp
) == 0) {
1489 catch_memory_errors
= 1;
1493 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1494 cflush((void *) adrs
);
1496 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1497 cinval((void *) adrs
);
1500 /* wait a little while to see if we get a machine check */
1503 catch_memory_errors
= 0;
1506 static unsigned long
1509 unsigned int instrs
[2];
1510 unsigned long (*code
)(void);
1511 unsigned long ret
= -1UL;
1513 unsigned long opd
[3];
1515 opd
[0] = (unsigned long)instrs
;
1518 code
= (unsigned long (*)(void)) opd
;
1520 code
= (unsigned long (*)(void)) instrs
;
1523 /* mfspr r3,n; blr */
1524 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1525 instrs
[1] = 0x4e800020;
1527 store_inst(instrs
+1);
1529 if (setjmp(bus_error_jmp
) == 0) {
1530 catch_memory_errors
= 1;
1536 /* wait a little while to see if we get a machine check */
1545 write_spr(int n
, unsigned long val
)
1547 unsigned int instrs
[2];
1548 unsigned long (*code
)(unsigned long);
1550 unsigned long opd
[3];
1552 opd
[0] = (unsigned long)instrs
;
1555 code
= (unsigned long (*)(unsigned long)) opd
;
1557 code
= (unsigned long (*)(unsigned long)) instrs
;
1560 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1561 instrs
[1] = 0x4e800020;
1563 store_inst(instrs
+1);
1565 if (setjmp(bus_error_jmp
) == 0) {
1566 catch_memory_errors
= 1;
1572 /* wait a little while to see if we get a machine check */
1578 static unsigned long regno
;
1579 extern char exc_prolog
;
1580 extern char dec_exc
;
1582 static void super_regs(void)
1589 unsigned long sp
, toc
;
1590 asm("mr %0,1" : "=r" (sp
) :);
1591 asm("mr %0,2" : "=r" (toc
) :);
1593 printf("msr = "REG
" sprg0= "REG
"\n",
1594 mfmsr(), mfspr(SPRN_SPRG0
));
1595 printf("pvr = "REG
" sprg1= "REG
"\n",
1596 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1597 printf("dec = "REG
" sprg2= "REG
"\n",
1598 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1599 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1600 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1601 #ifdef CONFIG_PPC_ISERIES
1602 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1603 struct paca_struct
*ptrPaca
;
1604 struct lppaca
*ptrLpPaca
;
1606 /* Dump out relevant Paca data areas. */
1608 ptrPaca
= get_paca();
1610 printf(" Local Processor Control Area (LpPaca): \n");
1611 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1612 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1613 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1614 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1615 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1616 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca
->saved_gpr5
);
1626 val
= read_spr(regno
);
1628 write_spr(regno
, val
);
1631 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1638 * Stuff for reading and writing memory safely
1641 mread(unsigned long adrs
, void *buf
, int size
)
1647 if (setjmp(bus_error_jmp
) == 0) {
1648 catch_memory_errors
= 1;
1654 *(u16
*)q
= *(u16
*)p
;
1657 *(u32
*)q
= *(u32
*)p
;
1660 *(u64
*)q
= *(u64
*)p
;
1663 for( ; n
< size
; ++n
) {
1669 /* wait a little while to see if we get a machine check */
1673 catch_memory_errors
= 0;
1678 mwrite(unsigned long adrs
, void *buf
, int size
)
1684 if (setjmp(bus_error_jmp
) == 0) {
1685 catch_memory_errors
= 1;
1691 *(u16
*)p
= *(u16
*)q
;
1694 *(u32
*)p
= *(u32
*)q
;
1697 *(u64
*)p
= *(u64
*)q
;
1700 for ( ; n
< size
; ++n
) {
1706 /* wait a little while to see if we get a machine check */
1710 printf("*** Error writing address %x\n", adrs
+ n
);
1712 catch_memory_errors
= 0;
1716 static int fault_type
;
1717 static int fault_except
;
1718 static char *fault_chars
[] = { "--", "**", "##" };
1720 static int handle_fault(struct pt_regs
*regs
)
1722 fault_except
= TRAP(regs
);
1723 switch (TRAP(regs
)) {
1735 longjmp(bus_error_jmp
, 1);
1740 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1743 byterev(unsigned char *val
, int size
)
1749 SWAP(val
[0], val
[1], t
);
1752 SWAP(val
[0], val
[3], t
);
1753 SWAP(val
[1], val
[2], t
);
1755 case 8: /* is there really any use for this? */
1756 SWAP(val
[0], val
[7], t
);
1757 SWAP(val
[1], val
[6], t
);
1758 SWAP(val
[2], val
[5], t
);
1759 SWAP(val
[3], val
[4], t
);
1767 static char *memex_help_string
=
1768 "Memory examine command usage:\n"
1769 "m [addr] [flags] examine/change memory\n"
1770 " addr is optional. will start where left off.\n"
1771 " flags may include chars from this set:\n"
1772 " b modify by bytes (default)\n"
1773 " w modify by words (2 byte)\n"
1774 " l modify by longs (4 byte)\n"
1775 " d modify by doubleword (8 byte)\n"
1776 " r toggle reverse byte order mode\n"
1777 " n do not read memory (for i/o spaces)\n"
1778 " . ok to read (default)\n"
1779 "NOTE: flags are saved as defaults\n"
1782 static char *memex_subcmd_help_string
=
1783 "Memory examine subcommands:\n"
1784 " hexval write this val to current location\n"
1785 " 'string' write chars from string to this location\n"
1786 " ' increment address\n"
1787 " ^ decrement address\n"
1788 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1789 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1790 " ` clear no-read flag\n"
1791 " ; stay at this addr\n"
1792 " v change to byte mode\n"
1793 " w change to word (2 byte) mode\n"
1794 " l change to long (4 byte) mode\n"
1795 " u change to doubleword (8 byte) mode\n"
1796 " m addr change current addr\n"
1797 " n toggle no-read flag\n"
1798 " r toggle byte reverse flag\n"
1799 " < count back up count bytes\n"
1800 " > count skip forward count bytes\n"
1801 " x exit this mode\n"
1807 int cmd
, inc
, i
, nslash
;
1809 unsigned char val
[16];
1811 scanhex((void *)&adrs
);
1814 printf(memex_help_string
);
1820 while ((cmd
= skipbl()) != '\n') {
1822 case 'b': size
= 1; break;
1823 case 'w': size
= 2; break;
1824 case 'l': size
= 4; break;
1825 case 'd': size
= 8; break;
1826 case 'r': brev
= !brev
; break;
1827 case 'n': mnoread
= 1; break;
1828 case '.': mnoread
= 0; break;
1837 n
= mread(adrs
, val
, size
);
1838 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1843 for (i
= 0; i
< n
; ++i
)
1844 printf("%.2x", val
[i
]);
1845 for (; i
< size
; ++i
)
1846 printf("%s", fault_chars
[fault_type
]);
1853 for (i
= 0; i
< size
; ++i
)
1854 val
[i
] = n
>> (i
* 8);
1857 mwrite(adrs
, val
, size
);
1870 else if( n
== '\'' )
1872 for (i
= 0; i
< size
; ++i
)
1873 val
[i
] = n
>> (i
* 8);
1876 mwrite(adrs
, val
, size
);
1913 adrs
-= 1 << nslash
;
1917 adrs
+= 1 << nslash
;
1921 adrs
+= 1 << -nslash
;
1925 adrs
-= 1 << -nslash
;
1928 scanhex((void *)&adrs
);
1947 printf(memex_subcmd_help_string
);
1962 case 'n': c
= '\n'; break;
1963 case 'r': c
= '\r'; break;
1964 case 'b': c
= '\b'; break;
1965 case 't': c
= '\t'; break;
1970 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1973 unsigned char temp
[16];
1975 for (n
= ndump
; n
> 0;) {
1977 nr
= mread(adrs
, temp
, r
);
1979 for (m
= 0; m
< r
; ++m
) {
1981 printf("%.2x", temp
[m
]);
1983 printf("%s", fault_chars
[fault_type
]);
1992 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1993 || ('a' <= (c) && (c) <= 'f') \
1994 || ('A' <= (c) && (c) <= 'F'))
2001 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2003 scanhex((void *)&adrs
);
2010 else if (nidump
> MAX_DUMP
)
2012 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2014 } else if (c
== 'l') {
2016 } else if (c
== 'r') {
2020 xmon_rawdump(adrs
, ndump
);
2027 else if (ndump
> MAX_DUMP
)
2029 prdump(adrs
, ndump
);
2036 prdump(unsigned long adrs
, long ndump
)
2038 long n
, m
, c
, r
, nr
;
2039 unsigned char temp
[16];
2041 for (n
= ndump
; n
> 0;) {
2045 nr
= mread(adrs
, temp
, r
);
2047 for (m
= 0; m
< r
; ++m
) {
2048 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2051 printf("%.2x", temp
[m
]);
2053 printf("%s", fault_chars
[fault_type
]);
2055 for (; m
< 16; ++m
) {
2056 if ((m
& (sizeof(long) - 1)) == 0)
2061 for (m
= 0; m
< r
; ++m
) {
2064 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2077 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2080 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2081 instruction_dump_func dump_func
)
2084 unsigned long first_adr
;
2085 unsigned long inst
, last_inst
= 0;
2086 unsigned char val
[4];
2089 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2090 nr
= mread(adr
, val
, 4);
2093 const char *x
= fault_chars
[fault_type
];
2094 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2098 inst
= GETWORD(val
);
2099 if (adr
> first_adr
&& inst
== last_inst
) {
2109 printf(REG
" %.8x", adr
, inst
);
2111 dump_func(inst
, adr
);
2114 return adr
- first_adr
;
2118 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2120 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2124 print_address(unsigned long addr
)
2126 xmon_print_symbol(addr
, "\t# ", "");
2132 const unsigned long size
= 128;
2133 unsigned long end
, addr
;
2134 unsigned char buf
[size
+ 1];
2139 if (setjmp(bus_error_jmp
) != 0) {
2140 printf("Unable to lookup symbol __log_buf!\n");
2144 catch_memory_errors
= 1;
2146 addr
= kallsyms_lookup_name("__log_buf");
2149 printf("Symbol __log_buf not found!\n");
2151 end
= addr
+ (1 << CONFIG_LOG_BUF_SHIFT
);
2152 while (addr
< end
) {
2153 if (! mread(addr
, buf
, size
)) {
2154 printf("Can't read memory at address 0x%lx\n", addr
);
2160 if (strlen(buf
) < size
)
2168 /* wait a little while to see if we get a machine check */
2170 catch_memory_errors
= 0;
2174 * Memory operations - move, set, print differences
2176 static unsigned long mdest
; /* destination address */
2177 static unsigned long msrc
; /* source address */
2178 static unsigned long mval
; /* byte value to set memory to */
2179 static unsigned long mcount
; /* # bytes to affect */
2180 static unsigned long mdiffs
; /* max # differences to print */
2185 scanhex((void *)&mdest
);
2186 if( termch
!= '\n' )
2188 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2189 if( termch
!= '\n' )
2191 scanhex((void *)&mcount
);
2194 memmove((void *)mdest
, (void *)msrc
, mcount
);
2197 memset((void *)mdest
, mval
, mcount
);
2200 if( termch
!= '\n' )
2202 scanhex((void *)&mdiffs
);
2203 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2209 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2214 for( n
= nb
; n
> 0; --n
)
2215 if( *p1
++ != *p2
++ )
2216 if( ++prt
<= maxpr
)
2217 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2218 p1
[-1], p2
- 1, p2
[-1]);
2220 printf("Total of %d differences\n", prt
);
2223 static unsigned mend
;
2224 static unsigned mask
;
2230 unsigned char val
[4];
2233 scanhex((void *)&mdest
);
2234 if (termch
!= '\n') {
2236 scanhex((void *)&mend
);
2237 if (termch
!= '\n') {
2239 scanhex((void *)&mval
);
2241 if (termch
!= '\n') termch
= 0;
2242 scanhex((void *)&mask
);
2246 for (a
= mdest
; a
< mend
; a
+= 4) {
2247 if (mread(a
, val
, 4) == 4
2248 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2249 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2256 static unsigned long mskip
= 0x1000;
2257 static unsigned long mlim
= 0xffffffff;
2267 if (termch
!= '\n') termch
= 0;
2269 if (termch
!= '\n') termch
= 0;
2272 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2273 ok
= mread(a
, &v
, 1);
2275 printf("%.8x .. ", a
);
2276 } else if (!ok
&& ook
)
2277 printf("%.8x\n", a
- mskip
);
2283 printf("%.8x\n", a
- mskip
);
2286 static void proccall(void)
2288 unsigned long args
[8];
2291 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2292 unsigned long, unsigned long, unsigned long,
2293 unsigned long, unsigned long, unsigned long);
2296 if (!scanhex(&adrs
))
2300 for (i
= 0; i
< 8; ++i
)
2302 for (i
= 0; i
< 8; ++i
) {
2303 if (!scanhex(&args
[i
]) || termch
== '\n')
2307 func
= (callfunc_t
) adrs
;
2309 if (setjmp(bus_error_jmp
) == 0) {
2310 catch_memory_errors
= 1;
2312 ret
= func(args
[0], args
[1], args
[2], args
[3],
2313 args
[4], args
[5], args
[6], args
[7]);
2315 printf("return value is %x\n", ret
);
2317 printf("*** %x exception occurred\n", fault_except
);
2319 catch_memory_errors
= 0;
2322 /* Input scanning routines */
2333 while( c
== ' ' || c
== '\t' )
2339 static char *regnames
[N_PTREGS
] = {
2340 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2341 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2342 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2343 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2344 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2350 "trap", "dar", "dsisr", "res"
2354 scanhex(unsigned long *vp
)
2361 /* parse register name */
2365 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2374 for (i
= 0; i
< N_PTREGS
; ++i
) {
2375 if (strcmp(regnames
[i
], regname
) == 0) {
2376 if (xmon_regs
== NULL
) {
2377 printf("regs not available\n");
2380 *vp
= ((unsigned long *)xmon_regs
)[i
];
2384 printf("invalid register name '%%%s'\n", regname
);
2388 /* skip leading "0x" if any */
2402 } else if (c
== '$') {
2404 for (i
=0; i
<63; i
++) {
2414 if (setjmp(bus_error_jmp
) == 0) {
2415 catch_memory_errors
= 1;
2417 *vp
= kallsyms_lookup_name(tmpstr
);
2420 catch_memory_errors
= 0;
2422 printf("unknown symbol '%s'\n", tmpstr
);
2455 static int hexdigit(int c
)
2457 if( '0' <= c
&& c
<= '9' )
2459 if( 'A' <= c
&& c
<= 'F' )
2460 return c
- ('A' - 10);
2461 if( 'a' <= c
&& c
<= 'f' )
2462 return c
- ('a' - 10);
2467 getstring(char *s
, int size
)
2478 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2483 static char line
[256];
2484 static char *lineptr
;
2495 if (lineptr
== NULL
|| *lineptr
== 0) {
2496 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2506 take_input(char *str
)
2515 int type
= inchar();
2517 static char tmp
[64];
2522 xmon_print_symbol(addr
, ": ", "\n");
2527 if (setjmp(bus_error_jmp
) == 0) {
2528 catch_memory_errors
= 1;
2530 addr
= kallsyms_lookup_name(tmp
);
2532 printf("%s: %lx\n", tmp
, addr
);
2534 printf("Symbol '%s' not found.\n", tmp
);
2537 catch_memory_errors
= 0;
2544 /* Print an address in numeric and symbolic form (if possible) */
2545 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2549 const char *name
= NULL
;
2550 unsigned long offset
, size
;
2552 printf(REG
, address
);
2553 if (setjmp(bus_error_jmp
) == 0) {
2554 catch_memory_errors
= 1;
2556 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2559 /* wait a little while to see if we get a machine check */
2563 catch_memory_errors
= 0;
2566 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2568 printf(" [%s]", modname
);
2570 printf("%s", after
);
2574 static void dump_slb(void)
2577 unsigned long esid
,vsid
,valid
;
2580 printf("SLB contents of cpu %x\n", smp_processor_id());
2582 for (i
= 0; i
< mmu_slb_size
; i
++) {
2583 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2584 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2585 valid
= (esid
& SLB_ESID_V
);
2586 if (valid
| esid
| vsid
) {
2587 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2589 llp
= vsid
& SLB_VSID_LLP
;
2590 if (vsid
& SLB_VSID_B_1T
) {
2591 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2593 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2596 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2598 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2607 static void dump_stab(void)
2610 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2612 printf("Segment table contents of cpu %x\n", smp_processor_id());
2614 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2621 printf("%03d %016lx ", i
, a
);
2622 printf("%016lx\n", b
);
2627 void dump_segments(void)
2629 if (cpu_has_feature(CPU_FTR_SLB
))
2636 #ifdef CONFIG_PPC_STD_MMU_32
2637 void dump_segments(void)
2642 for (i
= 0; i
< 16; ++i
)
2643 printf(" %x", mfsrin(i
));
2649 static void dump_tlb_44x(void)
2653 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2654 unsigned long w0
,w1
,w2
;
2655 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2656 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2657 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2658 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2659 if (w0
& PPC44x_TLB_VALID
) {
2660 printf("V %08x -> %01x%08x %c%c%c%c%c",
2661 w0
& PPC44x_TLB_EPN_MASK
,
2662 w1
& PPC44x_TLB_ERPN_MASK
,
2663 w1
& PPC44x_TLB_RPN_MASK
,
2664 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2665 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2666 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2667 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2668 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2673 #endif /* CONFIG_44x */
2675 static void xmon_init(int enable
)
2677 #ifdef CONFIG_PPC_ISERIES
2678 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2683 __debugger_ipi
= xmon_ipi
;
2684 __debugger_bpt
= xmon_bpt
;
2685 __debugger_sstep
= xmon_sstep
;
2686 __debugger_iabr_match
= xmon_iabr_match
;
2687 __debugger_dabr_match
= xmon_dabr_match
;
2688 __debugger_fault_handler
= xmon_fault_handler
;
2691 __debugger_ipi
= NULL
;
2692 __debugger_bpt
= NULL
;
2693 __debugger_sstep
= NULL
;
2694 __debugger_iabr_match
= NULL
;
2695 __debugger_dabr_match
= NULL
;
2696 __debugger_fault_handler
= NULL
;
2701 #ifdef CONFIG_MAGIC_SYSRQ
2702 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2704 /* ensure xmon is enabled */
2706 debugger(get_irq_regs());
2709 static struct sysrq_key_op sysrq_xmon_op
=
2711 .handler
= sysrq_handle_xmon
,
2713 .action_msg
= "Entering xmon",
2716 static int __init
setup_xmon_sysrq(void)
2718 #ifdef CONFIG_PPC_ISERIES
2719 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2722 register_sysrq_key('x', &sysrq_xmon_op
);
2725 __initcall(setup_xmon_sysrq
);
2726 #endif /* CONFIG_MAGIC_SYSRQ */
2728 static int __initdata xmon_early
, xmon_off
;
2730 static int __init
early_parse_xmon(char *p
)
2732 if (!p
|| strncmp(p
, "early", 5) == 0) {
2733 /* just "xmon" is equivalent to "xmon=early" */
2736 } else if (strncmp(p
, "on", 2) == 0)
2738 else if (strncmp(p
, "off", 3) == 0)
2740 else if (strncmp(p
, "nobt", 4) == 0)
2741 xmon_no_auto_backtrace
= 1;
2747 early_param("xmon", early_parse_xmon
);
2749 void __init
xmon_setup(void)
2751 #ifdef CONFIG_XMON_DEFAULT
2759 #ifdef CONFIG_SPU_BASE
2763 u64 saved_mfc_sr1_RW
;
2764 u32 saved_spu_runcntl_RW
;
2765 unsigned long dump_addr
;
2769 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2771 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2773 void xmon_register_spus(struct list_head
*list
)
2777 list_for_each_entry(spu
, list
, full_list
) {
2778 if (spu
->number
>= XMON_NUM_SPUS
) {
2783 spu_info
[spu
->number
].spu
= spu
;
2784 spu_info
[spu
->number
].stopped_ok
= 0;
2785 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2786 spu_info
[spu
->number
].spu
->local_store
;
2790 static void stop_spus(void)
2796 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2797 if (!spu_info
[i
].spu
)
2800 if (setjmp(bus_error_jmp
) == 0) {
2801 catch_memory_errors
= 1;
2804 spu
= spu_info
[i
].spu
;
2806 spu_info
[i
].saved_spu_runcntl_RW
=
2807 in_be32(&spu
->problem
->spu_runcntl_RW
);
2809 tmp
= spu_mfc_sr1_get(spu
);
2810 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2812 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2813 spu_mfc_sr1_set(spu
, tmp
);
2818 spu_info
[i
].stopped_ok
= 1;
2820 printf("Stopped spu %.2d (was %s)\n", i
,
2821 spu_info
[i
].saved_spu_runcntl_RW
?
2822 "running" : "stopped");
2824 catch_memory_errors
= 0;
2825 printf("*** Error stopping spu %.2d\n", i
);
2827 catch_memory_errors
= 0;
2831 static void restart_spus(void)
2836 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2837 if (!spu_info
[i
].spu
)
2840 if (!spu_info
[i
].stopped_ok
) {
2841 printf("*** Error, spu %d was not successfully stopped"
2842 ", not restarting\n", i
);
2846 if (setjmp(bus_error_jmp
) == 0) {
2847 catch_memory_errors
= 1;
2850 spu
= spu_info
[i
].spu
;
2851 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2852 out_be32(&spu
->problem
->spu_runcntl_RW
,
2853 spu_info
[i
].saved_spu_runcntl_RW
);
2858 printf("Restarted spu %.2d\n", i
);
2860 catch_memory_errors
= 0;
2861 printf("*** Error restarting spu %.2d\n", i
);
2863 catch_memory_errors
= 0;
2867 #define DUMP_WIDTH 23
2868 #define DUMP_VALUE(format, field, value) \
2870 if (setjmp(bus_error_jmp) == 0) { \
2871 catch_memory_errors = 1; \
2873 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2878 catch_memory_errors = 0; \
2879 printf(" %-*s = *** Error reading field.\n", \
2880 DUMP_WIDTH, #field); \
2882 catch_memory_errors = 0; \
2885 #define DUMP_FIELD(obj, format, field) \
2886 DUMP_VALUE(format, field, obj->field)
2888 static void dump_spu_fields(struct spu
*spu
)
2890 printf("Dumping spu fields at address %p:\n", spu
);
2892 DUMP_FIELD(spu
, "0x%x", number
);
2893 DUMP_FIELD(spu
, "%s", name
);
2894 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2895 DUMP_FIELD(spu
, "0x%p", local_store
);
2896 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2897 DUMP_FIELD(spu
, "0x%x", node
);
2898 DUMP_FIELD(spu
, "0x%lx", flags
);
2899 DUMP_FIELD(spu
, "%d", class_0_pending
);
2900 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
2901 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
2902 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
2903 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2904 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2905 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2906 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2907 DUMP_FIELD(spu
, "%d", pid
);
2908 DUMP_FIELD(spu
, "0x%p", mm
);
2909 DUMP_FIELD(spu
, "0x%p", ctx
);
2910 DUMP_FIELD(spu
, "0x%p", rq
);
2911 DUMP_FIELD(spu
, "0x%p", timestamp
);
2912 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2913 DUMP_FIELD(spu
, "0x%p", problem
);
2914 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2915 in_be32(&spu
->problem
->spu_runcntl_RW
));
2916 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2917 in_be32(&spu
->problem
->spu_status_R
));
2918 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2919 in_be32(&spu
->problem
->spu_npc_RW
));
2920 DUMP_FIELD(spu
, "0x%p", priv2
);
2921 DUMP_FIELD(spu
, "0x%p", pdata
);
2925 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2927 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2930 static void dump_spu_ls(unsigned long num
, int subcmd
)
2932 unsigned long offset
, addr
, ls_addr
;
2934 if (setjmp(bus_error_jmp
) == 0) {
2935 catch_memory_errors
= 1;
2937 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2941 catch_memory_errors
= 0;
2942 printf("*** Error: accessing spu info for spu %d\n", num
);
2945 catch_memory_errors
= 0;
2947 if (scanhex(&offset
))
2948 addr
= ls_addr
+ offset
;
2950 addr
= spu_info
[num
].dump_addr
;
2952 if (addr
>= ls_addr
+ LS_SIZE
) {
2953 printf("*** Error: address outside of local store\n");
2959 addr
+= spu_inst_dump(addr
, 16, 1);
2969 spu_info
[num
].dump_addr
= addr
;
2972 static int do_spu_cmd(void)
2974 static unsigned long num
= 0;
2975 int cmd
, subcmd
= 0;
2987 if (isxdigit(subcmd
) || subcmd
== '\n')
2991 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
2992 printf("*** Error: invalid spu number\n");
2998 dump_spu_fields(spu_info
[num
].spu
);
3001 dump_spu_ls(num
, subcmd
);
3012 #else /* ! CONFIG_SPU_BASE */
3013 static int do_spu_cmd(void)