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>
46 #include <asm/hvcall.h>
53 #define scanhex xmon_scanhex
54 #define skipbl xmon_skipbl
57 static cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
58 static unsigned long xmon_taken
= 1;
59 static int xmon_owner
;
61 #endif /* CONFIG_SMP */
63 static unsigned long in_xmon
= 0;
65 static unsigned long adrs
;
67 #define MAX_DUMP (128 * 1024)
68 static unsigned long ndump
= 64;
69 static unsigned long nidump
= 16;
70 static unsigned long ncsum
= 4096;
72 static char tmpstr
[128];
74 static long bus_error_jmp
[JMP_BUF_LEN
];
75 static int catch_memory_errors
;
76 static long *xmon_fault_jmp
[NR_CPUS
];
78 /* Breakpoint stuff */
80 unsigned long address
;
81 unsigned int instr
[2];
87 /* Bits in bpt.enabled */
88 #define BP_IABR_TE 1 /* IABR translation enabled */
94 static struct bpt bpts
[NBPTS
];
95 static struct bpt dabr
;
96 static struct bpt
*iabr
;
97 static unsigned bpinstr
= 0x7fe00008; /* trap */
99 #define BP_NUM(bp) ((bp) - bpts + 1)
102 static int cmds(struct pt_regs
*);
103 static int mread(unsigned long, void *, int);
104 static int mwrite(unsigned long, void *, int);
105 static int handle_fault(struct pt_regs
*);
106 static void byterev(unsigned char *, int);
107 static void memex(void);
108 static int bsesc(void);
109 static void dump(void);
110 static void prdump(unsigned long, long);
111 static int ppc_inst_dump(unsigned long, long, int);
112 static void backtrace(struct pt_regs
*);
113 static void excprint(struct pt_regs
*);
114 static void prregs(struct pt_regs
*);
115 static void memops(int);
116 static void memlocate(void);
117 static void memzcan(void);
118 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
120 int scanhex(unsigned long *valp
);
121 static void scannl(void);
122 static int hexdigit(int);
123 void getstring(char *, int);
124 static void flush_input(void);
125 static int inchar(void);
126 static void take_input(char *);
127 static unsigned long read_spr(int);
128 static void write_spr(int, unsigned long);
129 static void super_regs(void);
130 static void remove_bpts(void);
131 static void insert_bpts(void);
132 static void remove_cpu_bpts(void);
133 static void insert_cpu_bpts(void);
134 static struct bpt
*at_breakpoint(unsigned long pc
);
135 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
136 static int do_step(struct pt_regs
*);
137 static void bpt_cmds(void);
138 static void cacheflush(void);
139 static int cpu_cmd(void);
140 static void csum(void);
141 static void bootcmds(void);
142 static void proccall(void);
143 void dump_segments(void);
144 static void symbol_lookup(void);
145 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
147 static void xmon_print_symbol(unsigned long address
, const char *mid
,
149 static const char *getvecname(unsigned long vec
);
151 static int do_spu_cmd(void);
154 static void dump_tlb_44x(void);
157 static int xmon_no_auto_backtrace
;
159 extern void xmon_enter(void);
160 extern void xmon_leave(void);
162 extern void xmon_save_regs(struct pt_regs
*);
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 dr dump stream of raw bytes\n\
202 e print exception information\n\
204 la lookup symbol+offset of specified address\n\
205 ls lookup address of specified symbol\n\
206 m examine/change memory\n\
207 mm move a block of memory\n\
208 ms set a block of memory\n\
209 md compare two blocks of memory\n\
210 ml locate a block of memory\n\
211 mz zero a block of memory\n\
212 mi show information about memory allocation\n\
213 p call a procedure\n\
216 #ifdef CONFIG_SPU_BASE
217 " ss stop execution on all spus\n\
218 sr restore execution on stopped spus\n\
219 sf # dump spu fields for spu # (in hex)\n\
220 sd # dump spu local store for spu # (in hex)\n\
221 sdi # disassemble spu local store for spu # (in hex)\n"
223 " S print special registers\n\
225 x exit monitor and recover\n\
226 X exit monitor and dont recover\n"
228 " u dump segment table or SLB\n"
230 #ifdef CONFIG_PPC_STD_MMU_32
231 " u dump segment registers\n"
241 static struct pt_regs
*xmon_regs
;
243 static inline void sync(void)
245 asm volatile("sync; isync");
248 static inline void store_inst(void *p
)
250 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p
));
253 static inline void cflush(void *p
)
255 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p
));
258 static inline void cinval(void *p
)
260 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p
));
264 * Disable surveillance (the service processor watchdog function)
265 * while we are in xmon.
266 * XXX we should re-enable it when we leave. :)
268 #define SURVEILLANCE_TOKEN 9000
270 static inline void disable_surveillance(void)
272 #ifdef CONFIG_PPC_PSERIES
273 /* Since this can't be a module, args should end up below 4GB. */
274 static struct rtas_args args
;
277 * At this point we have got all the cpus we can into
278 * xmon, so there is hopefully no other cpu calling RTAS
279 * at the moment, even though we don't take rtas.lock.
280 * If we did try to take rtas.lock there would be a
281 * real possibility of deadlock.
283 args
.token
= rtas_token("set-indicator");
284 if (args
.token
== RTAS_UNKNOWN_SERVICE
)
288 args
.rets
= &args
.args
[3];
289 args
.args
[0] = SURVEILLANCE_TOKEN
;
292 enter_rtas(__pa(&args
));
293 #endif /* CONFIG_PPC_PSERIES */
297 static int xmon_speaker
;
299 static void get_output_lock(void)
301 int me
= smp_processor_id() + 0x100;
302 int last_speaker
= 0, prev
;
305 if (xmon_speaker
== me
)
308 if (xmon_speaker
== 0) {
309 last_speaker
= cmpxchg(&xmon_speaker
, 0, me
);
310 if (last_speaker
== 0)
314 while (xmon_speaker
== last_speaker
) {
317 /* hostile takeover */
318 prev
= cmpxchg(&xmon_speaker
, last_speaker
, me
);
319 if (prev
== last_speaker
)
326 static void release_output_lock(void)
331 int cpus_are_in_xmon(void)
333 return !cpus_empty(cpus_in_xmon
);
337 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
341 long recurse_jmp
[JMP_BUF_LEN
];
342 unsigned long offset
;
347 unsigned long timeout
;
350 local_irq_save(flags
);
352 bp
= in_breakpoint_table(regs
->nip
, &offset
);
354 regs
->nip
= bp
->address
+ offset
;
355 atomic_dec(&bp
->ref_count
);
361 cpu
= smp_processor_id();
362 if (cpu_isset(cpu
, cpus_in_xmon
)) {
365 printf("cpu 0x%x: Exception %lx %s in xmon, "
366 "returning to main loop\n",
367 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
368 release_output_lock();
369 longjmp(xmon_fault_jmp
[cpu
], 1);
372 if (setjmp(recurse_jmp
) != 0) {
373 if (!in_xmon
|| !xmon_gate
) {
375 printf("xmon: WARNING: bad recursive fault "
376 "on cpu 0x%x\n", cpu
);
377 release_output_lock();
380 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
384 xmon_fault_jmp
[cpu
] = recurse_jmp
;
385 cpu_set(cpu
, cpus_in_xmon
);
388 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
))
389 bp
= at_breakpoint(regs
->nip
);
390 if (bp
|| (regs
->msr
& MSR_RI
) == 0)
397 printf("cpu 0x%x stopped at breakpoint 0x%x (",
399 xmon_print_symbol(regs
->nip
, " ", ")\n");
401 if ((regs
->msr
& MSR_RI
) == 0)
402 printf("WARNING: exception is not recoverable, "
404 release_output_lock();
409 while (secondary
&& !xmon_gate
) {
413 secondary
= test_and_set_bit(0, &in_xmon
);
418 if (!secondary
&& !xmon_gate
) {
419 /* we are the first cpu to come in */
420 /* interrupt other cpu(s) */
421 int ncpus
= num_online_cpus();
426 smp_send_debugger_break(MSG_ALL_BUT_SELF
);
427 /* wait for other cpus to come in */
428 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
429 if (cpus_weight(cpus_in_xmon
) >= ncpus
)
435 disable_surveillance();
436 /* for breakpoint or single step, print the current instr. */
437 if (bp
|| TRAP(regs
) == 0xd00)
438 ppc_inst_dump(regs
->nip
, 1, 0);
439 printf("enter ? for help\n");
448 if (cpu
== xmon_owner
) {
449 if (!test_and_set_bit(0, &xmon_taken
)) {
454 while (cpu
== xmon_owner
)
468 /* have switched to some other cpu */
473 cpu_clear(cpu
, cpus_in_xmon
);
474 xmon_fault_jmp
[cpu
] = NULL
;
476 /* UP is simple... */
478 printf("Exception %lx %s in xmon, returning to main loop\n",
479 regs
->trap
, getvecname(TRAP(regs
)));
480 longjmp(xmon_fault_jmp
[0], 1);
482 if (setjmp(recurse_jmp
) == 0) {
483 xmon_fault_jmp
[0] = recurse_jmp
;
487 bp
= at_breakpoint(regs
->nip
);
489 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
490 xmon_print_symbol(regs
->nip
, " ", ")\n");
492 if ((regs
->msr
& MSR_RI
) == 0)
493 printf("WARNING: exception is not recoverable, "
496 disable_surveillance();
497 /* for breakpoint or single step, print the current instr. */
498 if (bp
|| TRAP(regs
) == 0xd00)
499 ppc_inst_dump(regs
->nip
, 1, 0);
500 printf("enter ? for help\n");
509 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
510 bp
= at_breakpoint(regs
->nip
);
512 int stepped
= emulate_step(regs
, bp
->instr
[0]);
514 regs
->nip
= (unsigned long) &bp
->instr
[0];
515 atomic_inc(&bp
->ref_count
);
516 } else if (stepped
< 0) {
517 printf("Couldn't single-step %s instruction\n",
518 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
525 local_irq_restore(flags
);
527 return cmd
!= 'X' && cmd
!= EOF
;
530 int xmon(struct pt_regs
*excp
)
535 xmon_save_regs(®s
);
539 return xmon_core(excp
, 0);
543 irqreturn_t
xmon_irq(int irq
, void *d
)
546 local_irq_save(flags
);
547 printf("Keyboard interrupt\n");
548 xmon(get_irq_regs());
549 local_irq_restore(flags
);
553 static int xmon_bpt(struct pt_regs
*regs
)
556 unsigned long offset
;
558 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
561 /* Are we at the trap at bp->instr[1] for some bp? */
562 bp
= in_breakpoint_table(regs
->nip
, &offset
);
563 if (bp
!= NULL
&& offset
== 4) {
564 regs
->nip
= bp
->address
+ 4;
565 atomic_dec(&bp
->ref_count
);
569 /* Are we at a breakpoint? */
570 bp
= at_breakpoint(regs
->nip
);
579 static int xmon_sstep(struct pt_regs
*regs
)
587 static int xmon_dabr_match(struct pt_regs
*regs
)
589 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
591 if (dabr
.enabled
== 0)
597 static int xmon_iabr_match(struct pt_regs
*regs
)
599 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
607 static int xmon_ipi(struct pt_regs
*regs
)
610 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
616 static int xmon_fault_handler(struct pt_regs
*regs
)
619 unsigned long offset
;
621 if (in_xmon
&& catch_memory_errors
)
622 handle_fault(regs
); /* doesn't return */
624 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
625 bp
= in_breakpoint_table(regs
->nip
, &offset
);
627 regs
->nip
= bp
->address
+ offset
;
628 atomic_dec(&bp
->ref_count
);
635 static struct bpt
*at_breakpoint(unsigned long pc
)
641 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
642 if (bp
->enabled
&& pc
== bp
->address
)
647 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
651 off
= nip
- (unsigned long) bpts
;
652 if (off
>= sizeof(bpts
))
654 off
%= sizeof(struct bpt
);
655 if (off
!= offsetof(struct bpt
, instr
[0])
656 && off
!= offsetof(struct bpt
, instr
[1]))
658 *offp
= off
- offsetof(struct bpt
, instr
[0]);
659 return (struct bpt
*) (nip
- off
);
662 static struct bpt
*new_breakpoint(unsigned long a
)
667 bp
= at_breakpoint(a
);
671 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
672 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
674 bp
->instr
[1] = bpinstr
;
675 store_inst(&bp
->instr
[1]);
680 printf("Sorry, no free breakpoints. Please clear one first.\n");
684 static void insert_bpts(void)
690 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
691 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
693 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
694 printf("Couldn't read instruction at %lx, "
695 "disabling breakpoint there\n", bp
->address
);
699 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
700 printf("Breakpoint at %lx is on an mtmsrd or rfid "
701 "instruction, disabling it\n", bp
->address
);
705 store_inst(&bp
->instr
[0]);
706 if (bp
->enabled
& BP_IABR
)
708 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
709 printf("Couldn't write instruction at %lx, "
710 "disabling breakpoint there\n", bp
->address
);
711 bp
->enabled
&= ~BP_TRAP
;
714 store_inst((void *)bp
->address
);
718 static void insert_cpu_bpts(void)
721 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
722 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
723 mtspr(SPRN_IABR
, iabr
->address
724 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
727 static void remove_bpts(void)
734 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
735 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
737 if (mread(bp
->address
, &instr
, 4) == 4
739 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
740 printf("Couldn't remove breakpoint at %lx\n",
743 store_inst((void *)bp
->address
);
747 static void remove_cpu_bpts(void)
750 if (cpu_has_feature(CPU_FTR_IABR
))
754 /* Command interpreting routine */
755 static char *last_cmd
;
758 cmds(struct pt_regs
*excp
)
765 if (!xmon_no_auto_backtrace
) {
766 xmon_no_auto_backtrace
= 1;
767 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
772 printf("%x:", smp_processor_id());
773 #endif /* CONFIG_SMP */
779 if (last_cmd
== NULL
)
781 take_input(last_cmd
);
815 prregs(excp
); /* print regs */
830 if (do_spu_cmd() == 0)
839 printf(" <no input ...>\n");
843 xmon_puts(help_string
);
861 #ifdef CONFIG_PPC_STD_MMU
872 printf("Unrecognized command: ");
874 if (' ' < cmd
&& cmd
<= '~')
877 printf("\\x%x", cmd
);
879 } while (cmd
!= '\n');
880 printf(" (type ? for help)\n");
887 * Step a single instruction.
888 * Some instructions we emulate, others we execute with MSR_SE set.
890 static int do_step(struct pt_regs
*regs
)
895 /* check we are in 64-bit kernel mode, translation enabled */
896 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
897 if (mread(regs
->nip
, &instr
, 4) == 4) {
898 stepped
= emulate_step(regs
, instr
);
900 printf("Couldn't single-step %s instruction\n",
901 (IS_RFID(instr
)? "rfid": "mtmsrd"));
905 regs
->trap
= 0xd00 | (regs
->trap
& 1);
906 printf("stepped to ");
907 xmon_print_symbol(regs
->nip
, " ", "\n");
908 ppc_inst_dump(regs
->nip
, 1, 0);
917 static void bootcmds(void)
923 ppc_md
.restart(NULL
);
930 static int cpu_cmd(void)
937 if (!scanhex(&cpu
)) {
938 /* print cpus waiting or in xmon */
939 printf("cpus stopped:");
941 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
942 if (cpu_isset(cpu
, cpus_in_xmon
)) {
948 printf("-%x", cpu
- 1);
953 printf("-%x", NR_CPUS
- 1);
957 /* try to switch to cpu specified */
958 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
959 printf("cpu 0x%x isn't in xmon\n", cpu
);
966 while (!xmon_taken
) {
967 if (--timeout
== 0) {
968 if (test_and_set_bit(0, &xmon_taken
))
970 /* take control back */
972 xmon_owner
= smp_processor_id();
973 printf("cpu %u didn't take control\n", cpu
);
981 #endif /* CONFIG_SMP */
984 static unsigned short fcstab
[256] = {
985 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
986 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
987 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
988 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
989 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
990 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
991 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
992 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
993 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
994 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
995 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
996 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
997 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
998 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
999 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1000 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1001 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1002 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1003 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1004 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1005 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1006 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1007 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1008 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1009 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1010 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1011 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1012 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1013 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1014 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1015 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1016 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1019 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1028 if (!scanhex(&adrs
))
1030 if (!scanhex(&ncsum
))
1033 for (i
= 0; i
< ncsum
; ++i
) {
1034 if (mread(adrs
+i
, &v
, 1) == 0) {
1035 printf("csum stopped at %x\n", adrs
+i
);
1040 printf("%x\n", fcs
);
1044 * Check if this is a suitable place to put a breakpoint.
1046 static long check_bp_loc(unsigned long addr
)
1051 if (!is_kernel_addr(addr
)) {
1052 printf("Breakpoints may only be placed at kernel addresses\n");
1055 if (!mread(addr
, &instr
, sizeof(instr
))) {
1056 printf("Can't read instruction at address %lx\n", addr
);
1059 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1060 printf("Breakpoints may not be placed on mtmsrd or rfid "
1067 static char *breakpoint_help_string
=
1068 "Breakpoint command usage:\n"
1069 "b show breakpoints\n"
1070 "b <addr> [cnt] set breakpoint at given instr addr\n"
1071 "bc clear all breakpoints\n"
1072 "bc <n/addr> clear breakpoint number n or at addr\n"
1073 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1074 "bd <addr> [cnt] set hardware data breakpoint\n"
1084 const char badaddr
[] = "Only kernel addresses are permitted "
1085 "for breakpoints\n";
1090 case 'd': /* bd - hardware data breakpoint */
1095 else if (cmd
== 'w')
1101 if (scanhex(&dabr
.address
)) {
1102 if (!is_kernel_addr(dabr
.address
)) {
1107 dabr
.enabled
= mode
| BP_DABR
;
1111 case 'i': /* bi - hardware instr breakpoint */
1112 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1113 printf("Hardware instruction breakpoint "
1114 "not supported on this cpu\n");
1118 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1123 if (!check_bp_loc(a
))
1125 bp
= new_breakpoint(a
);
1127 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1135 /* clear all breakpoints */
1136 for (i
= 0; i
< NBPTS
; ++i
)
1137 bpts
[i
].enabled
= 0;
1140 printf("All breakpoints cleared\n");
1144 if (a
<= NBPTS
&& a
>= 1) {
1145 /* assume a breakpoint number */
1146 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1148 /* assume a breakpoint address */
1149 bp
= at_breakpoint(a
);
1151 printf("No breakpoint at %x\n", a
);
1156 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1157 xmon_print_symbol(bp
->address
, " ", ")\n");
1165 printf(breakpoint_help_string
);
1170 /* print all breakpoints */
1171 printf(" type address\n");
1173 printf(" data "REG
" [", dabr
.address
);
1174 if (dabr
.enabled
& 1)
1176 if (dabr
.enabled
& 2)
1180 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1183 printf("%2x %s ", BP_NUM(bp
),
1184 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1185 xmon_print_symbol(bp
->address
, " ", "\n");
1190 if (!check_bp_loc(a
))
1192 bp
= new_breakpoint(a
);
1194 bp
->enabled
|= BP_TRAP
;
1199 /* Very cheap human name for vector lookup. */
1201 const char *getvecname(unsigned long vec
)
1206 case 0x100: ret
= "(System Reset)"; break;
1207 case 0x200: ret
= "(Machine Check)"; break;
1208 case 0x300: ret
= "(Data Access)"; break;
1209 case 0x380: ret
= "(Data SLB Access)"; break;
1210 case 0x400: ret
= "(Instruction Access)"; break;
1211 case 0x480: ret
= "(Instruction SLB Access)"; break;
1212 case 0x500: ret
= "(Hardware Interrupt)"; break;
1213 case 0x600: ret
= "(Alignment)"; break;
1214 case 0x700: ret
= "(Program Check)"; break;
1215 case 0x800: ret
= "(FPU Unavailable)"; break;
1216 case 0x900: ret
= "(Decrementer)"; break;
1217 case 0xc00: ret
= "(System Call)"; break;
1218 case 0xd00: ret
= "(Single Step)"; break;
1219 case 0xf00: ret
= "(Performance Monitor)"; break;
1220 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1221 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1227 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1228 unsigned long *endp
)
1230 unsigned long size
, offset
;
1233 *startp
= *endp
= 0;
1236 if (setjmp(bus_error_jmp
) == 0) {
1237 catch_memory_errors
= 1;
1239 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1241 *startp
= pc
- offset
;
1242 *endp
= pc
- offset
+ size
;
1246 catch_memory_errors
= 0;
1249 static int xmon_depth_to_print
= 64;
1251 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1252 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1254 #ifdef __powerpc64__
1255 #define REGS_OFFSET 0x70
1257 #define REGS_OFFSET 16
1260 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1264 unsigned long newsp
;
1265 unsigned long marker
;
1267 struct pt_regs regs
;
1270 if (sp
< PAGE_OFFSET
) {
1272 printf("SP (%lx) is in userspace\n", sp
);
1276 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1277 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1278 printf("Couldn't read stack frame at %lx\n", sp
);
1283 * For the first stack frame, try to work out if
1284 * LR and/or the saved LR value in the bottommost
1285 * stack frame are valid.
1287 if ((pc
| lr
) != 0) {
1288 unsigned long fnstart
, fnend
;
1289 unsigned long nextip
;
1292 get_function_bounds(pc
, &fnstart
, &fnend
);
1295 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1296 sizeof(unsigned long));
1298 if (lr
< PAGE_OFFSET
1299 || (fnstart
<= lr
&& lr
< fnend
))
1301 } else if (lr
== nextip
) {
1303 } else if (lr
>= PAGE_OFFSET
1304 && !(fnstart
<= lr
&& lr
< fnend
)) {
1305 printf("[link register ] ");
1306 xmon_print_symbol(lr
, " ", "\n");
1309 printf("["REG
"] ", sp
);
1310 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1315 printf("["REG
"] ", sp
);
1316 xmon_print_symbol(ip
, " ", "\n");
1319 /* Look for "regshere" marker to see if this is
1320 an exception frame. */
1321 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1322 && marker
== STACK_FRAME_REGS_MARKER
) {
1323 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1325 printf("Couldn't read registers at %lx\n",
1329 printf("--- Exception: %lx %s at ", regs
.trap
,
1330 getvecname(TRAP(®s
)));
1333 xmon_print_symbol(pc
, " ", "\n");
1340 } while (count
++ < xmon_depth_to_print
);
1343 static void backtrace(struct pt_regs
*excp
)
1348 xmon_show_stack(sp
, 0, 0);
1350 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1354 static void print_bug_trap(struct pt_regs
*regs
)
1357 const struct bug_entry
*bug
;
1360 if (regs
->msr
& MSR_PR
)
1361 return; /* not in kernel */
1362 addr
= regs
->nip
; /* address of trap instruction */
1363 if (addr
< PAGE_OFFSET
)
1365 bug
= find_bug(regs
->nip
);
1368 if (is_warning_bug(bug
))
1371 #ifdef CONFIG_DEBUG_BUGVERBOSE
1372 printf("kernel BUG at %s:%u!\n",
1373 bug
->file
, bug
->line
);
1375 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1377 #endif /* CONFIG_BUG */
1380 static void excprint(struct pt_regs
*fp
)
1385 printf("cpu 0x%x: ", smp_processor_id());
1386 #endif /* CONFIG_SMP */
1389 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1391 xmon_print_symbol(fp
->nip
, ": ", "\n");
1393 printf(" lr: ", fp
->link
);
1394 xmon_print_symbol(fp
->link
, ": ", "\n");
1396 printf(" sp: %lx\n", fp
->gpr
[1]);
1397 printf(" msr: %lx\n", fp
->msr
);
1399 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1400 printf(" dar: %lx\n", fp
->dar
);
1402 printf(" dsisr: %lx\n", fp
->dsisr
);
1405 printf(" current = 0x%lx\n", current
);
1407 printf(" paca = 0x%lx\n", get_paca());
1410 printf(" pid = %ld, comm = %s\n",
1411 current
->pid
, current
->comm
);
1418 static void prregs(struct pt_regs
*fp
)
1422 struct pt_regs regs
;
1424 if (scanhex(&base
)) {
1425 if (setjmp(bus_error_jmp
) == 0) {
1426 catch_memory_errors
= 1;
1428 regs
= *(struct pt_regs
*)base
;
1432 catch_memory_errors
= 0;
1433 printf("*** Error reading registers from "REG
"\n",
1437 catch_memory_errors
= 0;
1442 if (FULL_REGS(fp
)) {
1443 for (n
= 0; n
< 16; ++n
)
1444 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1445 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1447 for (n
= 0; n
< 7; ++n
)
1448 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1449 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1452 for (n
= 0; n
< 32; ++n
) {
1453 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1454 (n
& 3) == 3? "\n": " ");
1455 if (n
== 12 && !FULL_REGS(fp
)) {
1462 xmon_print_symbol(fp
->nip
, " ", "\n");
1464 xmon_print_symbol(fp
->link
, " ", "\n");
1465 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1466 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1467 fp
->ctr
, fp
->xer
, fp
->trap
);
1469 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1470 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1473 static void cacheflush(void)
1476 unsigned long nflush
;
1481 scanhex((void *)&adrs
);
1486 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1487 if (setjmp(bus_error_jmp
) == 0) {
1488 catch_memory_errors
= 1;
1492 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1493 cflush((void *) adrs
);
1495 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1496 cinval((void *) adrs
);
1499 /* wait a little while to see if we get a machine check */
1502 catch_memory_errors
= 0;
1505 static unsigned long
1508 unsigned int instrs
[2];
1509 unsigned long (*code
)(void);
1510 unsigned long ret
= -1UL;
1512 unsigned long opd
[3];
1514 opd
[0] = (unsigned long)instrs
;
1517 code
= (unsigned long (*)(void)) opd
;
1519 code
= (unsigned long (*)(void)) instrs
;
1522 /* mfspr r3,n; blr */
1523 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1524 instrs
[1] = 0x4e800020;
1526 store_inst(instrs
+1);
1528 if (setjmp(bus_error_jmp
) == 0) {
1529 catch_memory_errors
= 1;
1535 /* wait a little while to see if we get a machine check */
1544 write_spr(int n
, unsigned long val
)
1546 unsigned int instrs
[2];
1547 unsigned long (*code
)(unsigned long);
1549 unsigned long opd
[3];
1551 opd
[0] = (unsigned long)instrs
;
1554 code
= (unsigned long (*)(unsigned long)) opd
;
1556 code
= (unsigned long (*)(unsigned long)) instrs
;
1559 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1560 instrs
[1] = 0x4e800020;
1562 store_inst(instrs
+1);
1564 if (setjmp(bus_error_jmp
) == 0) {
1565 catch_memory_errors
= 1;
1571 /* wait a little while to see if we get a machine check */
1577 static unsigned long regno
;
1578 extern char exc_prolog
;
1579 extern char dec_exc
;
1581 static void super_regs(void)
1588 unsigned long sp
, toc
;
1589 asm("mr %0,1" : "=r" (sp
) :);
1590 asm("mr %0,2" : "=r" (toc
) :);
1592 printf("msr = "REG
" sprg0= "REG
"\n",
1593 mfmsr(), mfspr(SPRN_SPRG0
));
1594 printf("pvr = "REG
" sprg1= "REG
"\n",
1595 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1596 printf("dec = "REG
" sprg2= "REG
"\n",
1597 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1598 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1599 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1600 #ifdef CONFIG_PPC_ISERIES
1601 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1602 struct paca_struct
*ptrPaca
;
1603 struct lppaca
*ptrLpPaca
;
1605 /* Dump out relevant Paca data areas. */
1607 ptrPaca
= get_paca();
1609 printf(" Local Processor Control Area (LpPaca): \n");
1610 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1611 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1612 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1613 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1614 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1615 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca
->saved_gpr5
);
1625 val
= read_spr(regno
);
1627 write_spr(regno
, val
);
1630 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1637 * Stuff for reading and writing memory safely
1640 mread(unsigned long adrs
, void *buf
, int size
)
1646 if (setjmp(bus_error_jmp
) == 0) {
1647 catch_memory_errors
= 1;
1653 *(u16
*)q
= *(u16
*)p
;
1656 *(u32
*)q
= *(u32
*)p
;
1659 *(u64
*)q
= *(u64
*)p
;
1662 for( ; n
< size
; ++n
) {
1668 /* wait a little while to see if we get a machine check */
1672 catch_memory_errors
= 0;
1677 mwrite(unsigned long adrs
, void *buf
, int size
)
1683 if (setjmp(bus_error_jmp
) == 0) {
1684 catch_memory_errors
= 1;
1690 *(u16
*)p
= *(u16
*)q
;
1693 *(u32
*)p
= *(u32
*)q
;
1696 *(u64
*)p
= *(u64
*)q
;
1699 for ( ; n
< size
; ++n
) {
1705 /* wait a little while to see if we get a machine check */
1709 printf("*** Error writing address %x\n", adrs
+ n
);
1711 catch_memory_errors
= 0;
1715 static int fault_type
;
1716 static int fault_except
;
1717 static char *fault_chars
[] = { "--", "**", "##" };
1719 static int handle_fault(struct pt_regs
*regs
)
1721 fault_except
= TRAP(regs
);
1722 switch (TRAP(regs
)) {
1734 longjmp(bus_error_jmp
, 1);
1739 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1742 byterev(unsigned char *val
, int size
)
1748 SWAP(val
[0], val
[1], t
);
1751 SWAP(val
[0], val
[3], t
);
1752 SWAP(val
[1], val
[2], t
);
1754 case 8: /* is there really any use for this? */
1755 SWAP(val
[0], val
[7], t
);
1756 SWAP(val
[1], val
[6], t
);
1757 SWAP(val
[2], val
[5], t
);
1758 SWAP(val
[3], val
[4], t
);
1766 static char *memex_help_string
=
1767 "Memory examine command usage:\n"
1768 "m [addr] [flags] examine/change memory\n"
1769 " addr is optional. will start where left off.\n"
1770 " flags may include chars from this set:\n"
1771 " b modify by bytes (default)\n"
1772 " w modify by words (2 byte)\n"
1773 " l modify by longs (4 byte)\n"
1774 " d modify by doubleword (8 byte)\n"
1775 " r toggle reverse byte order mode\n"
1776 " n do not read memory (for i/o spaces)\n"
1777 " . ok to read (default)\n"
1778 "NOTE: flags are saved as defaults\n"
1781 static char *memex_subcmd_help_string
=
1782 "Memory examine subcommands:\n"
1783 " hexval write this val to current location\n"
1784 " 'string' write chars from string to this location\n"
1785 " ' increment address\n"
1786 " ^ decrement address\n"
1787 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1788 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1789 " ` clear no-read flag\n"
1790 " ; stay at this addr\n"
1791 " v change to byte mode\n"
1792 " w change to word (2 byte) mode\n"
1793 " l change to long (4 byte) mode\n"
1794 " u change to doubleword (8 byte) mode\n"
1795 " m addr change current addr\n"
1796 " n toggle no-read flag\n"
1797 " r toggle byte reverse flag\n"
1798 " < count back up count bytes\n"
1799 " > count skip forward count bytes\n"
1800 " x exit this mode\n"
1806 int cmd
, inc
, i
, nslash
;
1808 unsigned char val
[16];
1810 scanhex((void *)&adrs
);
1813 printf(memex_help_string
);
1819 while ((cmd
= skipbl()) != '\n') {
1821 case 'b': size
= 1; break;
1822 case 'w': size
= 2; break;
1823 case 'l': size
= 4; break;
1824 case 'd': size
= 8; break;
1825 case 'r': brev
= !brev
; break;
1826 case 'n': mnoread
= 1; break;
1827 case '.': mnoread
= 0; break;
1836 n
= mread(adrs
, val
, size
);
1837 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1842 for (i
= 0; i
< n
; ++i
)
1843 printf("%.2x", val
[i
]);
1844 for (; i
< size
; ++i
)
1845 printf("%s", fault_chars
[fault_type
]);
1852 for (i
= 0; i
< size
; ++i
)
1853 val
[i
] = n
>> (i
* 8);
1856 mwrite(adrs
, val
, size
);
1869 else if( n
== '\'' )
1871 for (i
= 0; i
< size
; ++i
)
1872 val
[i
] = n
>> (i
* 8);
1875 mwrite(adrs
, val
, size
);
1912 adrs
-= 1 << nslash
;
1916 adrs
+= 1 << nslash
;
1920 adrs
+= 1 << -nslash
;
1924 adrs
-= 1 << -nslash
;
1927 scanhex((void *)&adrs
);
1946 printf(memex_subcmd_help_string
);
1961 case 'n': c
= '\n'; break;
1962 case 'r': c
= '\r'; break;
1963 case 'b': c
= '\b'; break;
1964 case 't': c
= '\t'; break;
1969 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1972 unsigned char temp
[16];
1974 for (n
= ndump
; n
> 0;) {
1976 nr
= mread(adrs
, temp
, r
);
1978 for (m
= 0; m
< r
; ++m
) {
1980 printf("%.2x", temp
[m
]);
1982 printf("%s", fault_chars
[fault_type
]);
1991 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1992 || ('a' <= (c) && (c) <= 'f') \
1993 || ('A' <= (c) && (c) <= 'F'))
2000 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2002 scanhex((void *)&adrs
);
2009 else if (nidump
> MAX_DUMP
)
2011 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2013 } else if (c
== 'r') {
2017 xmon_rawdump(adrs
, ndump
);
2024 else if (ndump
> MAX_DUMP
)
2026 prdump(adrs
, ndump
);
2033 prdump(unsigned long adrs
, long ndump
)
2035 long n
, m
, c
, r
, nr
;
2036 unsigned char temp
[16];
2038 for (n
= ndump
; n
> 0;) {
2042 nr
= mread(adrs
, temp
, r
);
2044 for (m
= 0; m
< r
; ++m
) {
2045 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2048 printf("%.2x", temp
[m
]);
2050 printf("%s", fault_chars
[fault_type
]);
2052 for (; m
< 16; ++m
) {
2053 if ((m
& (sizeof(long) - 1)) == 0)
2058 for (m
= 0; m
< r
; ++m
) {
2061 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2074 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2077 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2078 instruction_dump_func dump_func
)
2081 unsigned long first_adr
;
2082 unsigned long inst
, last_inst
= 0;
2083 unsigned char val
[4];
2086 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2087 nr
= mread(adr
, val
, 4);
2090 const char *x
= fault_chars
[fault_type
];
2091 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2095 inst
= GETWORD(val
);
2096 if (adr
> first_adr
&& inst
== last_inst
) {
2106 printf(REG
" %.8x", adr
, inst
);
2108 dump_func(inst
, adr
);
2111 return adr
- first_adr
;
2115 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2117 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2121 print_address(unsigned long addr
)
2123 xmon_print_symbol(addr
, "\t# ", "");
2128 * Memory operations - move, set, print differences
2130 static unsigned long mdest
; /* destination address */
2131 static unsigned long msrc
; /* source address */
2132 static unsigned long mval
; /* byte value to set memory to */
2133 static unsigned long mcount
; /* # bytes to affect */
2134 static unsigned long mdiffs
; /* max # differences to print */
2139 scanhex((void *)&mdest
);
2140 if( termch
!= '\n' )
2142 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2143 if( termch
!= '\n' )
2145 scanhex((void *)&mcount
);
2148 memmove((void *)mdest
, (void *)msrc
, mcount
);
2151 memset((void *)mdest
, mval
, mcount
);
2154 if( termch
!= '\n' )
2156 scanhex((void *)&mdiffs
);
2157 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2163 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2168 for( n
= nb
; n
> 0; --n
)
2169 if( *p1
++ != *p2
++ )
2170 if( ++prt
<= maxpr
)
2171 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2172 p1
[-1], p2
- 1, p2
[-1]);
2174 printf("Total of %d differences\n", prt
);
2177 static unsigned mend
;
2178 static unsigned mask
;
2184 unsigned char val
[4];
2187 scanhex((void *)&mdest
);
2188 if (termch
!= '\n') {
2190 scanhex((void *)&mend
);
2191 if (termch
!= '\n') {
2193 scanhex((void *)&mval
);
2195 if (termch
!= '\n') termch
= 0;
2196 scanhex((void *)&mask
);
2200 for (a
= mdest
; a
< mend
; a
+= 4) {
2201 if (mread(a
, val
, 4) == 4
2202 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2203 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2210 static unsigned long mskip
= 0x1000;
2211 static unsigned long mlim
= 0xffffffff;
2221 if (termch
!= '\n') termch
= 0;
2223 if (termch
!= '\n') termch
= 0;
2226 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2227 ok
= mread(a
, &v
, 1);
2229 printf("%.8x .. ", a
);
2230 } else if (!ok
&& ook
)
2231 printf("%.8x\n", a
- mskip
);
2237 printf("%.8x\n", a
- mskip
);
2240 static void proccall(void)
2242 unsigned long args
[8];
2245 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2246 unsigned long, unsigned long, unsigned long,
2247 unsigned long, unsigned long, unsigned long);
2250 if (!scanhex(&adrs
))
2254 for (i
= 0; i
< 8; ++i
)
2256 for (i
= 0; i
< 8; ++i
) {
2257 if (!scanhex(&args
[i
]) || termch
== '\n')
2261 func
= (callfunc_t
) adrs
;
2263 if (setjmp(bus_error_jmp
) == 0) {
2264 catch_memory_errors
= 1;
2266 ret
= func(args
[0], args
[1], args
[2], args
[3],
2267 args
[4], args
[5], args
[6], args
[7]);
2269 printf("return value is %x\n", ret
);
2271 printf("*** %x exception occurred\n", fault_except
);
2273 catch_memory_errors
= 0;
2276 /* Input scanning routines */
2287 while( c
== ' ' || c
== '\t' )
2293 static char *regnames
[N_PTREGS
] = {
2294 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2295 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2296 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2297 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2298 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2304 "trap", "dar", "dsisr", "res"
2308 scanhex(unsigned long *vp
)
2315 /* parse register name */
2319 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2328 for (i
= 0; i
< N_PTREGS
; ++i
) {
2329 if (strcmp(regnames
[i
], regname
) == 0) {
2330 if (xmon_regs
== NULL
) {
2331 printf("regs not available\n");
2334 *vp
= ((unsigned long *)xmon_regs
)[i
];
2338 printf("invalid register name '%%%s'\n", regname
);
2342 /* skip leading "0x" if any */
2356 } else if (c
== '$') {
2358 for (i
=0; i
<63; i
++) {
2368 if (setjmp(bus_error_jmp
) == 0) {
2369 catch_memory_errors
= 1;
2371 *vp
= kallsyms_lookup_name(tmpstr
);
2374 catch_memory_errors
= 0;
2376 printf("unknown symbol '%s'\n", tmpstr
);
2409 static int hexdigit(int c
)
2411 if( '0' <= c
&& c
<= '9' )
2413 if( 'A' <= c
&& c
<= 'F' )
2414 return c
- ('A' - 10);
2415 if( 'a' <= c
&& c
<= 'f' )
2416 return c
- ('a' - 10);
2421 getstring(char *s
, int size
)
2432 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2437 static char line
[256];
2438 static char *lineptr
;
2449 if (lineptr
== NULL
|| *lineptr
== 0) {
2450 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2460 take_input(char *str
)
2469 int type
= inchar();
2471 static char tmp
[64];
2476 xmon_print_symbol(addr
, ": ", "\n");
2481 if (setjmp(bus_error_jmp
) == 0) {
2482 catch_memory_errors
= 1;
2484 addr
= kallsyms_lookup_name(tmp
);
2486 printf("%s: %lx\n", tmp
, addr
);
2488 printf("Symbol '%s' not found.\n", tmp
);
2491 catch_memory_errors
= 0;
2498 /* Print an address in numeric and symbolic form (if possible) */
2499 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2503 const char *name
= NULL
;
2504 unsigned long offset
, size
;
2506 printf(REG
, address
);
2507 if (setjmp(bus_error_jmp
) == 0) {
2508 catch_memory_errors
= 1;
2510 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2513 /* wait a little while to see if we get a machine check */
2517 catch_memory_errors
= 0;
2520 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2522 printf(" [%s]", modname
);
2524 printf("%s", after
);
2528 static void dump_slb(void)
2531 unsigned long esid
,vsid
,valid
;
2534 printf("SLB contents of cpu %x\n", smp_processor_id());
2536 for (i
= 0; i
< mmu_slb_size
; i
++) {
2537 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2538 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2539 valid
= (esid
& SLB_ESID_V
);
2540 if (valid
| esid
| vsid
) {
2541 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2543 llp
= vsid
& SLB_VSID_LLP
;
2544 if (vsid
& SLB_VSID_B_1T
) {
2545 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2547 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2550 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2552 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2561 static void dump_stab(void)
2564 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2566 printf("Segment table contents of cpu %x\n", smp_processor_id());
2568 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2575 printf("%03d %016lx ", i
, a
);
2576 printf("%016lx\n", b
);
2581 void dump_segments(void)
2583 if (cpu_has_feature(CPU_FTR_SLB
))
2590 #ifdef CONFIG_PPC_STD_MMU_32
2591 void dump_segments(void)
2596 for (i
= 0; i
< 16; ++i
)
2597 printf(" %x", mfsrin(i
));
2603 static void dump_tlb_44x(void)
2607 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2608 unsigned long w0
,w1
,w2
;
2609 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2610 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2611 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2612 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2613 if (w0
& PPC44x_TLB_VALID
) {
2614 printf("V %08x -> %01x%08x %c%c%c%c%c",
2615 w0
& PPC44x_TLB_EPN_MASK
,
2616 w1
& PPC44x_TLB_ERPN_MASK
,
2617 w1
& PPC44x_TLB_RPN_MASK
,
2618 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2619 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2620 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2621 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2622 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2627 #endif /* CONFIG_44x */
2629 static void xmon_init(int enable
)
2631 #ifdef CONFIG_PPC_ISERIES
2632 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2637 __debugger_ipi
= xmon_ipi
;
2638 __debugger_bpt
= xmon_bpt
;
2639 __debugger_sstep
= xmon_sstep
;
2640 __debugger_iabr_match
= xmon_iabr_match
;
2641 __debugger_dabr_match
= xmon_dabr_match
;
2642 __debugger_fault_handler
= xmon_fault_handler
;
2645 __debugger_ipi
= NULL
;
2646 __debugger_bpt
= NULL
;
2647 __debugger_sstep
= NULL
;
2648 __debugger_iabr_match
= NULL
;
2649 __debugger_dabr_match
= NULL
;
2650 __debugger_fault_handler
= NULL
;
2655 #ifdef CONFIG_MAGIC_SYSRQ
2656 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2658 /* ensure xmon is enabled */
2660 debugger(get_irq_regs());
2663 static struct sysrq_key_op sysrq_xmon_op
=
2665 .handler
= sysrq_handle_xmon
,
2667 .action_msg
= "Entering xmon",
2670 static int __init
setup_xmon_sysrq(void)
2672 #ifdef CONFIG_PPC_ISERIES
2673 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2676 register_sysrq_key('x', &sysrq_xmon_op
);
2679 __initcall(setup_xmon_sysrq
);
2680 #endif /* CONFIG_MAGIC_SYSRQ */
2682 static int __initdata xmon_early
, xmon_off
;
2684 static int __init
early_parse_xmon(char *p
)
2686 if (!p
|| strncmp(p
, "early", 5) == 0) {
2687 /* just "xmon" is equivalent to "xmon=early" */
2690 } else if (strncmp(p
, "on", 2) == 0)
2692 else if (strncmp(p
, "off", 3) == 0)
2694 else if (strncmp(p
, "nobt", 4) == 0)
2695 xmon_no_auto_backtrace
= 1;
2701 early_param("xmon", early_parse_xmon
);
2703 void __init
xmon_setup(void)
2705 #ifdef CONFIG_XMON_DEFAULT
2713 #ifdef CONFIG_SPU_BASE
2717 u64 saved_mfc_sr1_RW
;
2718 u32 saved_spu_runcntl_RW
;
2719 unsigned long dump_addr
;
2723 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2725 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2727 void xmon_register_spus(struct list_head
*list
)
2731 list_for_each_entry(spu
, list
, full_list
) {
2732 if (spu
->number
>= XMON_NUM_SPUS
) {
2737 spu_info
[spu
->number
].spu
= spu
;
2738 spu_info
[spu
->number
].stopped_ok
= 0;
2739 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2740 spu_info
[spu
->number
].spu
->local_store
;
2744 static void stop_spus(void)
2750 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2751 if (!spu_info
[i
].spu
)
2754 if (setjmp(bus_error_jmp
) == 0) {
2755 catch_memory_errors
= 1;
2758 spu
= spu_info
[i
].spu
;
2760 spu_info
[i
].saved_spu_runcntl_RW
=
2761 in_be32(&spu
->problem
->spu_runcntl_RW
);
2763 tmp
= spu_mfc_sr1_get(spu
);
2764 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2766 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2767 spu_mfc_sr1_set(spu
, tmp
);
2772 spu_info
[i
].stopped_ok
= 1;
2774 printf("Stopped spu %.2d (was %s)\n", i
,
2775 spu_info
[i
].saved_spu_runcntl_RW
?
2776 "running" : "stopped");
2778 catch_memory_errors
= 0;
2779 printf("*** Error stopping spu %.2d\n", i
);
2781 catch_memory_errors
= 0;
2785 static void restart_spus(void)
2790 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2791 if (!spu_info
[i
].spu
)
2794 if (!spu_info
[i
].stopped_ok
) {
2795 printf("*** Error, spu %d was not successfully stopped"
2796 ", not restarting\n", i
);
2800 if (setjmp(bus_error_jmp
) == 0) {
2801 catch_memory_errors
= 1;
2804 spu
= spu_info
[i
].spu
;
2805 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2806 out_be32(&spu
->problem
->spu_runcntl_RW
,
2807 spu_info
[i
].saved_spu_runcntl_RW
);
2812 printf("Restarted spu %.2d\n", i
);
2814 catch_memory_errors
= 0;
2815 printf("*** Error restarting spu %.2d\n", i
);
2817 catch_memory_errors
= 0;
2821 #define DUMP_WIDTH 23
2822 #define DUMP_VALUE(format, field, value) \
2824 if (setjmp(bus_error_jmp) == 0) { \
2825 catch_memory_errors = 1; \
2827 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2832 catch_memory_errors = 0; \
2833 printf(" %-*s = *** Error reading field.\n", \
2834 DUMP_WIDTH, #field); \
2836 catch_memory_errors = 0; \
2839 #define DUMP_FIELD(obj, format, field) \
2840 DUMP_VALUE(format, field, obj->field)
2842 static void dump_spu_fields(struct spu
*spu
)
2844 printf("Dumping spu fields at address %p:\n", spu
);
2846 DUMP_FIELD(spu
, "0x%x", number
);
2847 DUMP_FIELD(spu
, "%s", name
);
2848 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2849 DUMP_FIELD(spu
, "0x%p", local_store
);
2850 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2851 DUMP_FIELD(spu
, "0x%x", node
);
2852 DUMP_FIELD(spu
, "0x%lx", flags
);
2853 DUMP_FIELD(spu
, "%d", class_0_pending
);
2854 DUMP_FIELD(spu
, "0x%lx", class_0_dar
);
2855 DUMP_FIELD(spu
, "0x%lx", class_1_dar
);
2856 DUMP_FIELD(spu
, "0x%lx", class_1_dsisr
);
2857 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2858 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2859 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2860 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2861 DUMP_FIELD(spu
, "%d", pid
);
2862 DUMP_FIELD(spu
, "0x%p", mm
);
2863 DUMP_FIELD(spu
, "0x%p", ctx
);
2864 DUMP_FIELD(spu
, "0x%p", rq
);
2865 DUMP_FIELD(spu
, "0x%p", timestamp
);
2866 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2867 DUMP_FIELD(spu
, "0x%p", problem
);
2868 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2869 in_be32(&spu
->problem
->spu_runcntl_RW
));
2870 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2871 in_be32(&spu
->problem
->spu_status_R
));
2872 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2873 in_be32(&spu
->problem
->spu_npc_RW
));
2874 DUMP_FIELD(spu
, "0x%p", priv2
);
2875 DUMP_FIELD(spu
, "0x%p", pdata
);
2879 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2881 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2884 static void dump_spu_ls(unsigned long num
, int subcmd
)
2886 unsigned long offset
, addr
, ls_addr
;
2888 if (setjmp(bus_error_jmp
) == 0) {
2889 catch_memory_errors
= 1;
2891 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2895 catch_memory_errors
= 0;
2896 printf("*** Error: accessing spu info for spu %d\n", num
);
2899 catch_memory_errors
= 0;
2901 if (scanhex(&offset
))
2902 addr
= ls_addr
+ offset
;
2904 addr
= spu_info
[num
].dump_addr
;
2906 if (addr
>= ls_addr
+ LS_SIZE
) {
2907 printf("*** Error: address outside of local store\n");
2913 addr
+= spu_inst_dump(addr
, 16, 1);
2923 spu_info
[num
].dump_addr
= addr
;
2926 static int do_spu_cmd(void)
2928 static unsigned long num
= 0;
2929 int cmd
, subcmd
= 0;
2941 if (isxdigit(subcmd
) || subcmd
== '\n')
2945 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
2946 printf("*** Error: invalid spu number\n");
2952 dump_spu_fields(spu_info
[num
].spu
);
2955 dump_spu_ls(num
, subcmd
);
2966 #else /* ! CONFIG_SPU_BASE */
2967 static int do_spu_cmd(void)