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>
48 #include <asm/iseries/it_lp_reg_save.h>
54 #define scanhex xmon_scanhex
55 #define skipbl xmon_skipbl
58 cpumask_t cpus_in_xmon
= CPU_MASK_NONE
;
59 static unsigned long xmon_taken
= 1;
60 static int xmon_owner
;
62 #endif /* CONFIG_SMP */
64 static unsigned long in_xmon
= 0;
66 static unsigned long adrs
;
68 #define MAX_DUMP (128 * 1024)
69 static unsigned long ndump
= 64;
70 static unsigned long nidump
= 16;
71 static unsigned long ncsum
= 4096;
73 static char tmpstr
[128];
75 static long bus_error_jmp
[JMP_BUF_LEN
];
76 static int catch_memory_errors
;
77 static long *xmon_fault_jmp
[NR_CPUS
];
79 /* Breakpoint stuff */
81 unsigned long address
;
82 unsigned int instr
[2];
88 /* Bits in bpt.enabled */
89 #define BP_IABR_TE 1 /* IABR translation enabled */
95 static struct bpt bpts
[NBPTS
];
96 static struct bpt dabr
;
97 static struct bpt
*iabr
;
98 static unsigned bpinstr
= 0x7fe00008; /* trap */
100 #define BP_NUM(bp) ((bp) - bpts + 1)
103 static int cmds(struct pt_regs
*);
104 static int mread(unsigned long, void *, int);
105 static int mwrite(unsigned long, void *, int);
106 static int handle_fault(struct pt_regs
*);
107 static void byterev(unsigned char *, int);
108 static void memex(void);
109 static int bsesc(void);
110 static void dump(void);
111 static void prdump(unsigned long, long);
112 static int ppc_inst_dump(unsigned long, long, int);
113 static void backtrace(struct pt_regs
*);
114 static void excprint(struct pt_regs
*);
115 static void prregs(struct pt_regs
*);
116 static void memops(int);
117 static void memlocate(void);
118 static void memzcan(void);
119 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
121 int scanhex(unsigned long *valp
);
122 static void scannl(void);
123 static int hexdigit(int);
124 void getstring(char *, int);
125 static void flush_input(void);
126 static int inchar(void);
127 static void take_input(char *);
128 static unsigned long read_spr(int);
129 static void write_spr(int, unsigned long);
130 static void super_regs(void);
131 static void remove_bpts(void);
132 static void insert_bpts(void);
133 static void remove_cpu_bpts(void);
134 static void insert_cpu_bpts(void);
135 static struct bpt
*at_breakpoint(unsigned long pc
);
136 static struct bpt
*in_breakpoint_table(unsigned long pc
, unsigned long *offp
);
137 static int do_step(struct pt_regs
*);
138 static void bpt_cmds(void);
139 static void cacheflush(void);
140 static int cpu_cmd(void);
141 static void csum(void);
142 static void bootcmds(void);
143 static void proccall(void);
144 void dump_segments(void);
145 static void symbol_lookup(void);
146 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
148 static void xmon_print_symbol(unsigned long address
, const char *mid
,
150 static const char *getvecname(unsigned long vec
);
152 static int do_spu_cmd(void);
155 static void dump_tlb_44x(void);
158 int xmon_no_auto_backtrace
;
160 extern void xmon_enter(void);
161 extern void xmon_leave(void);
163 extern void xmon_save_regs(struct pt_regs
*);
167 #define REGS_PER_LINE 4
168 #define LAST_VOLATILE 13
171 #define REGS_PER_LINE 8
172 #define LAST_VOLATILE 12
175 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
177 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
178 || ('a' <= (c) && (c) <= 'f') \
179 || ('A' <= (c) && (c) <= 'F'))
180 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
181 || ('a' <= (c) && (c) <= 'z') \
182 || ('A' <= (c) && (c) <= 'Z'))
183 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
185 static char *help_string
= "\
187 b show breakpoints\n\
188 bd set data breakpoint\n\
189 bi set instruction breakpoint\n\
190 bc clear breakpoint\n"
193 c print cpus stopped in xmon\n\
194 c# try to switch to cpu number h (in hex)\n"
199 di dump instructions\n\
200 df dump float values\n\
201 dd dump double values\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)
333 static int xmon_core(struct pt_regs
*regs
, int fromipi
)
337 long recurse_jmp
[JMP_BUF_LEN
];
338 unsigned long offset
;
343 unsigned long timeout
;
346 local_irq_save(flags
);
348 bp
= in_breakpoint_table(regs
->nip
, &offset
);
350 regs
->nip
= bp
->address
+ offset
;
351 atomic_dec(&bp
->ref_count
);
357 cpu
= smp_processor_id();
358 if (cpu_isset(cpu
, cpus_in_xmon
)) {
361 printf("cpu 0x%x: Exception %lx %s in xmon, "
362 "returning to main loop\n",
363 cpu
, regs
->trap
, getvecname(TRAP(regs
)));
364 release_output_lock();
365 longjmp(xmon_fault_jmp
[cpu
], 1);
368 if (setjmp(recurse_jmp
) != 0) {
369 if (!in_xmon
|| !xmon_gate
) {
371 printf("xmon: WARNING: bad recursive fault "
372 "on cpu 0x%x\n", cpu
);
373 release_output_lock();
376 secondary
= !(xmon_taken
&& cpu
== xmon_owner
);
380 xmon_fault_jmp
[cpu
] = recurse_jmp
;
381 cpu_set(cpu
, cpus_in_xmon
);
384 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
))
385 bp
= at_breakpoint(regs
->nip
);
386 if (bp
|| (regs
->msr
& MSR_RI
) == 0)
393 printf("cpu 0x%x stopped at breakpoint 0x%x (",
395 xmon_print_symbol(regs
->nip
, " ", ")\n");
397 if ((regs
->msr
& MSR_RI
) == 0)
398 printf("WARNING: exception is not recoverable, "
400 release_output_lock();
405 while (secondary
&& !xmon_gate
) {
409 secondary
= test_and_set_bit(0, &in_xmon
);
414 if (!secondary
&& !xmon_gate
) {
415 /* we are the first cpu to come in */
416 /* interrupt other cpu(s) */
417 int ncpus
= num_online_cpus();
422 smp_send_debugger_break(MSG_ALL_BUT_SELF
);
423 /* wait for other cpus to come in */
424 for (timeout
= 100000000; timeout
!= 0; --timeout
) {
425 if (cpus_weight(cpus_in_xmon
) >= ncpus
)
431 disable_surveillance();
432 /* for breakpoint or single step, print the current instr. */
433 if (bp
|| TRAP(regs
) == 0xd00)
434 ppc_inst_dump(regs
->nip
, 1, 0);
435 printf("enter ? for help\n");
444 if (cpu
== xmon_owner
) {
445 if (!test_and_set_bit(0, &xmon_taken
)) {
450 while (cpu
== xmon_owner
)
464 /* have switched to some other cpu */
469 cpu_clear(cpu
, cpus_in_xmon
);
470 xmon_fault_jmp
[cpu
] = NULL
;
472 /* UP is simple... */
474 printf("Exception %lx %s in xmon, returning to main loop\n",
475 regs
->trap
, getvecname(TRAP(regs
)));
476 longjmp(xmon_fault_jmp
[0], 1);
478 if (setjmp(recurse_jmp
) == 0) {
479 xmon_fault_jmp
[0] = recurse_jmp
;
483 bp
= at_breakpoint(regs
->nip
);
485 printf("Stopped at breakpoint %x (", BP_NUM(bp
));
486 xmon_print_symbol(regs
->nip
, " ", ")\n");
488 if ((regs
->msr
& MSR_RI
) == 0)
489 printf("WARNING: exception is not recoverable, "
492 disable_surveillance();
493 /* for breakpoint or single step, print the current instr. */
494 if (bp
|| TRAP(regs
) == 0xd00)
495 ppc_inst_dump(regs
->nip
, 1, 0);
496 printf("enter ? for help\n");
505 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
506 bp
= at_breakpoint(regs
->nip
);
508 int stepped
= emulate_step(regs
, bp
->instr
[0]);
510 regs
->nip
= (unsigned long) &bp
->instr
[0];
511 atomic_inc(&bp
->ref_count
);
512 } else if (stepped
< 0) {
513 printf("Couldn't single-step %s instruction\n",
514 (IS_RFID(bp
->instr
[0])? "rfid": "mtmsrd"));
521 local_irq_restore(flags
);
523 return cmd
!= 'X' && cmd
!= EOF
;
526 int xmon(struct pt_regs
*excp
)
531 xmon_save_regs(®s
);
535 return xmon_core(excp
, 0);
539 irqreturn_t
xmon_irq(int irq
, void *d
)
542 local_irq_save(flags
);
543 printf("Keyboard interrupt\n");
544 xmon(get_irq_regs());
545 local_irq_restore(flags
);
549 static int xmon_bpt(struct pt_regs
*regs
)
552 unsigned long offset
;
554 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
557 /* Are we at the trap at bp->instr[1] for some bp? */
558 bp
= in_breakpoint_table(regs
->nip
, &offset
);
559 if (bp
!= NULL
&& offset
== 4) {
560 regs
->nip
= bp
->address
+ 4;
561 atomic_dec(&bp
->ref_count
);
565 /* Are we at a breakpoint? */
566 bp
= at_breakpoint(regs
->nip
);
575 static int xmon_sstep(struct pt_regs
*regs
)
583 static int xmon_dabr_match(struct pt_regs
*regs
)
585 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
587 if (dabr
.enabled
== 0)
593 static int xmon_iabr_match(struct pt_regs
*regs
)
595 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) != (MSR_IR
|MSR_SF
))
603 static int xmon_ipi(struct pt_regs
*regs
)
606 if (in_xmon
&& !cpu_isset(smp_processor_id(), cpus_in_xmon
))
612 static int xmon_fault_handler(struct pt_regs
*regs
)
615 unsigned long offset
;
617 if (in_xmon
&& catch_memory_errors
)
618 handle_fault(regs
); /* doesn't return */
620 if ((regs
->msr
& (MSR_IR
|MSR_PR
|MSR_SF
)) == (MSR_IR
|MSR_SF
)) {
621 bp
= in_breakpoint_table(regs
->nip
, &offset
);
623 regs
->nip
= bp
->address
+ offset
;
624 atomic_dec(&bp
->ref_count
);
631 static struct bpt
*at_breakpoint(unsigned long pc
)
637 for (i
= 0; i
< NBPTS
; ++i
, ++bp
)
638 if (bp
->enabled
&& pc
== bp
->address
)
643 static struct bpt
*in_breakpoint_table(unsigned long nip
, unsigned long *offp
)
647 off
= nip
- (unsigned long) bpts
;
648 if (off
>= sizeof(bpts
))
650 off
%= sizeof(struct bpt
);
651 if (off
!= offsetof(struct bpt
, instr
[0])
652 && off
!= offsetof(struct bpt
, instr
[1]))
654 *offp
= off
- offsetof(struct bpt
, instr
[0]);
655 return (struct bpt
*) (nip
- off
);
658 static struct bpt
*new_breakpoint(unsigned long a
)
663 bp
= at_breakpoint(a
);
667 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
668 if (!bp
->enabled
&& atomic_read(&bp
->ref_count
) == 0) {
670 bp
->instr
[1] = bpinstr
;
671 store_inst(&bp
->instr
[1]);
676 printf("Sorry, no free breakpoints. Please clear one first.\n");
680 static void insert_bpts(void)
686 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
687 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) == 0)
689 if (mread(bp
->address
, &bp
->instr
[0], 4) != 4) {
690 printf("Couldn't read instruction at %lx, "
691 "disabling breakpoint there\n", bp
->address
);
695 if (IS_MTMSRD(bp
->instr
[0]) || IS_RFID(bp
->instr
[0])) {
696 printf("Breakpoint at %lx is on an mtmsrd or rfid "
697 "instruction, disabling it\n", bp
->address
);
701 store_inst(&bp
->instr
[0]);
702 if (bp
->enabled
& BP_IABR
)
704 if (mwrite(bp
->address
, &bpinstr
, 4) != 4) {
705 printf("Couldn't write instruction at %lx, "
706 "disabling breakpoint there\n", bp
->address
);
707 bp
->enabled
&= ~BP_TRAP
;
710 store_inst((void *)bp
->address
);
714 static void insert_cpu_bpts(void)
717 set_dabr(dabr
.address
| (dabr
.enabled
& 7));
718 if (iabr
&& cpu_has_feature(CPU_FTR_IABR
))
719 mtspr(SPRN_IABR
, iabr
->address
720 | (iabr
->enabled
& (BP_IABR
|BP_IABR_TE
)));
723 static void remove_bpts(void)
730 for (i
= 0; i
< NBPTS
; ++i
, ++bp
) {
731 if ((bp
->enabled
& (BP_TRAP
|BP_IABR
)) != BP_TRAP
)
733 if (mread(bp
->address
, &instr
, 4) == 4
735 && mwrite(bp
->address
, &bp
->instr
, 4) != 4)
736 printf("Couldn't remove breakpoint at %lx\n",
739 store_inst((void *)bp
->address
);
743 static void remove_cpu_bpts(void)
746 if (cpu_has_feature(CPU_FTR_IABR
))
750 /* Command interpreting routine */
751 static char *last_cmd
;
754 cmds(struct pt_regs
*excp
)
761 if (!xmon_no_auto_backtrace
) {
762 xmon_no_auto_backtrace
= 1;
763 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
768 printf("%x:", smp_processor_id());
769 #endif /* CONFIG_SMP */
775 if (last_cmd
== NULL
)
777 take_input(last_cmd
);
811 prregs(excp
); /* print regs */
826 if (do_spu_cmd() == 0)
835 printf(" <no input ...>\n");
839 xmon_puts(help_string
);
857 #ifdef CONFIG_PPC_STD_MMU
868 printf("Unrecognized command: ");
870 if (' ' < cmd
&& cmd
<= '~')
873 printf("\\x%x", cmd
);
875 } while (cmd
!= '\n');
876 printf(" (type ? for help)\n");
883 * Step a single instruction.
884 * Some instructions we emulate, others we execute with MSR_SE set.
886 static int do_step(struct pt_regs
*regs
)
891 /* check we are in 64-bit kernel mode, translation enabled */
892 if ((regs
->msr
& (MSR_SF
|MSR_PR
|MSR_IR
)) == (MSR_SF
|MSR_IR
)) {
893 if (mread(regs
->nip
, &instr
, 4) == 4) {
894 stepped
= emulate_step(regs
, instr
);
896 printf("Couldn't single-step %s instruction\n",
897 (IS_RFID(instr
)? "rfid": "mtmsrd"));
901 regs
->trap
= 0xd00 | (regs
->trap
& 1);
902 printf("stepped to ");
903 xmon_print_symbol(regs
->nip
, " ", "\n");
904 ppc_inst_dump(regs
->nip
, 1, 0);
913 static void bootcmds(void)
919 ppc_md
.restart(NULL
);
926 static int cpu_cmd(void)
933 if (!scanhex(&cpu
)) {
934 /* print cpus waiting or in xmon */
935 printf("cpus stopped:");
937 for (cpu
= 0; cpu
< NR_CPUS
; ++cpu
) {
938 if (cpu_isset(cpu
, cpus_in_xmon
)) {
944 printf("-%x", cpu
- 1);
949 printf("-%x", NR_CPUS
- 1);
953 /* try to switch to cpu specified */
954 if (!cpu_isset(cpu
, cpus_in_xmon
)) {
955 printf("cpu 0x%x isn't in xmon\n", cpu
);
962 while (!xmon_taken
) {
963 if (--timeout
== 0) {
964 if (test_and_set_bit(0, &xmon_taken
))
966 /* take control back */
968 xmon_owner
= smp_processor_id();
969 printf("cpu %u didn't take control\n", cpu
);
977 #endif /* CONFIG_SMP */
980 static unsigned short fcstab
[256] = {
981 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
982 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
983 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
984 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
985 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
986 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
987 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
988 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
989 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
990 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
991 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
992 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
993 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
994 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
995 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
996 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
997 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
998 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
999 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1000 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1001 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1002 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1003 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1004 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1005 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1006 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1007 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1008 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1009 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1010 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1011 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1012 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1015 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1024 if (!scanhex(&adrs
))
1026 if (!scanhex(&ncsum
))
1029 for (i
= 0; i
< ncsum
; ++i
) {
1030 if (mread(adrs
+i
, &v
, 1) == 0) {
1031 printf("csum stopped at %x\n", adrs
+i
);
1036 printf("%x\n", fcs
);
1040 * Check if this is a suitable place to put a breakpoint.
1042 static long check_bp_loc(unsigned long addr
)
1047 if (!is_kernel_addr(addr
)) {
1048 printf("Breakpoints may only be placed at kernel addresses\n");
1051 if (!mread(addr
, &instr
, sizeof(instr
))) {
1052 printf("Can't read instruction at address %lx\n", addr
);
1055 if (IS_MTMSRD(instr
) || IS_RFID(instr
)) {
1056 printf("Breakpoints may not be placed on mtmsrd or rfid "
1063 static char *breakpoint_help_string
=
1064 "Breakpoint command usage:\n"
1065 "b show breakpoints\n"
1066 "b <addr> [cnt] set breakpoint at given instr addr\n"
1067 "bc clear all breakpoints\n"
1068 "bc <n/addr> clear breakpoint number n or at addr\n"
1069 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1070 "bd <addr> [cnt] set hardware data breakpoint\n"
1080 const char badaddr
[] = "Only kernel addresses are permitted "
1081 "for breakpoints\n";
1086 case 'd': /* bd - hardware data breakpoint */
1091 else if (cmd
== 'w')
1097 if (scanhex(&dabr
.address
)) {
1098 if (!is_kernel_addr(dabr
.address
)) {
1103 dabr
.enabled
= mode
| BP_DABR
;
1107 case 'i': /* bi - hardware instr breakpoint */
1108 if (!cpu_has_feature(CPU_FTR_IABR
)) {
1109 printf("Hardware instruction breakpoint "
1110 "not supported on this cpu\n");
1114 iabr
->enabled
&= ~(BP_IABR
| BP_IABR_TE
);
1119 if (!check_bp_loc(a
))
1121 bp
= new_breakpoint(a
);
1123 bp
->enabled
|= BP_IABR
| BP_IABR_TE
;
1131 /* clear all breakpoints */
1132 for (i
= 0; i
< NBPTS
; ++i
)
1133 bpts
[i
].enabled
= 0;
1136 printf("All breakpoints cleared\n");
1140 if (a
<= NBPTS
&& a
>= 1) {
1141 /* assume a breakpoint number */
1142 bp
= &bpts
[a
-1]; /* bp nums are 1 based */
1144 /* assume a breakpoint address */
1145 bp
= at_breakpoint(a
);
1147 printf("No breakpoint at %x\n", a
);
1152 printf("Cleared breakpoint %x (", BP_NUM(bp
));
1153 xmon_print_symbol(bp
->address
, " ", ")\n");
1161 printf(breakpoint_help_string
);
1166 /* print all breakpoints */
1167 printf(" type address\n");
1169 printf(" data "REG
" [", dabr
.address
);
1170 if (dabr
.enabled
& 1)
1172 if (dabr
.enabled
& 2)
1176 for (bp
= bpts
; bp
< &bpts
[NBPTS
]; ++bp
) {
1179 printf("%2x %s ", BP_NUM(bp
),
1180 (bp
->enabled
& BP_IABR
)? "inst": "trap");
1181 xmon_print_symbol(bp
->address
, " ", "\n");
1186 if (!check_bp_loc(a
))
1188 bp
= new_breakpoint(a
);
1190 bp
->enabled
|= BP_TRAP
;
1195 /* Very cheap human name for vector lookup. */
1197 const char *getvecname(unsigned long vec
)
1202 case 0x100: ret
= "(System Reset)"; break;
1203 case 0x200: ret
= "(Machine Check)"; break;
1204 case 0x300: ret
= "(Data Access)"; break;
1205 case 0x380: ret
= "(Data SLB Access)"; break;
1206 case 0x400: ret
= "(Instruction Access)"; break;
1207 case 0x480: ret
= "(Instruction SLB Access)"; break;
1208 case 0x500: ret
= "(Hardware Interrupt)"; break;
1209 case 0x600: ret
= "(Alignment)"; break;
1210 case 0x700: ret
= "(Program Check)"; break;
1211 case 0x800: ret
= "(FPU Unavailable)"; break;
1212 case 0x900: ret
= "(Decrementer)"; break;
1213 case 0xc00: ret
= "(System Call)"; break;
1214 case 0xd00: ret
= "(Single Step)"; break;
1215 case 0xf00: ret
= "(Performance Monitor)"; break;
1216 case 0xf20: ret
= "(Altivec Unavailable)"; break;
1217 case 0x1300: ret
= "(Instruction Breakpoint)"; break;
1223 static void get_function_bounds(unsigned long pc
, unsigned long *startp
,
1224 unsigned long *endp
)
1226 unsigned long size
, offset
;
1229 *startp
= *endp
= 0;
1232 if (setjmp(bus_error_jmp
) == 0) {
1233 catch_memory_errors
= 1;
1235 name
= kallsyms_lookup(pc
, &size
, &offset
, NULL
, tmpstr
);
1237 *startp
= pc
- offset
;
1238 *endp
= pc
- offset
+ size
;
1242 catch_memory_errors
= 0;
1245 static int xmon_depth_to_print
= 64;
1248 #define LRSAVE_OFFSET 0x10
1249 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1250 #define MARKER_OFFSET 0x60
1251 #define REGS_OFFSET 0x70
1253 #define LRSAVE_OFFSET 4
1254 #define REG_FRAME_MARKER 0x72656773
1255 #define MARKER_OFFSET 8
1256 #define REGS_OFFSET 16
1259 static void xmon_show_stack(unsigned long sp
, unsigned long lr
,
1263 unsigned long newsp
;
1264 unsigned long marker
;
1266 struct pt_regs regs
;
1269 if (sp
< PAGE_OFFSET
) {
1271 printf("SP (%lx) is in userspace\n", sp
);
1275 if (!mread(sp
+ LRSAVE_OFFSET
, &ip
, sizeof(unsigned long))
1276 || !mread(sp
, &newsp
, sizeof(unsigned long))) {
1277 printf("Couldn't read stack frame at %lx\n", sp
);
1282 * For the first stack frame, try to work out if
1283 * LR and/or the saved LR value in the bottommost
1284 * stack frame are valid.
1286 if ((pc
| lr
) != 0) {
1287 unsigned long fnstart
, fnend
;
1288 unsigned long nextip
;
1291 get_function_bounds(pc
, &fnstart
, &fnend
);
1294 mread(newsp
+ LRSAVE_OFFSET
, &nextip
,
1295 sizeof(unsigned long));
1297 if (lr
< PAGE_OFFSET
1298 || (fnstart
<= lr
&& lr
< fnend
))
1300 } else if (lr
== nextip
) {
1302 } else if (lr
>= PAGE_OFFSET
1303 && !(fnstart
<= lr
&& lr
< fnend
)) {
1304 printf("[link register ] ");
1305 xmon_print_symbol(lr
, " ", "\n");
1308 printf("["REG
"] ", sp
);
1309 xmon_print_symbol(ip
, " ", " (unreliable)\n");
1314 printf("["REG
"] ", sp
);
1315 xmon_print_symbol(ip
, " ", "\n");
1318 /* Look for "regshere" marker to see if this is
1319 an exception frame. */
1320 if (mread(sp
+ MARKER_OFFSET
, &marker
, sizeof(unsigned long))
1321 && marker
== REG_FRAME_MARKER
) {
1322 if (mread(sp
+ REGS_OFFSET
, ®s
, sizeof(regs
))
1324 printf("Couldn't read registers at %lx\n",
1328 printf("--- Exception: %lx %s at ", regs
.trap
,
1329 getvecname(TRAP(®s
)));
1332 xmon_print_symbol(pc
, " ", "\n");
1339 } while (count
++ < xmon_depth_to_print
);
1342 static void backtrace(struct pt_regs
*excp
)
1347 xmon_show_stack(sp
, 0, 0);
1349 xmon_show_stack(excp
->gpr
[1], excp
->link
, excp
->nip
);
1353 static void print_bug_trap(struct pt_regs
*regs
)
1355 const struct bug_entry
*bug
;
1358 if (regs
->msr
& MSR_PR
)
1359 return; /* not in kernel */
1360 addr
= regs
->nip
; /* address of trap instruction */
1361 if (addr
< PAGE_OFFSET
)
1363 bug
= find_bug(regs
->nip
);
1366 if (is_warning_bug(bug
))
1369 #ifdef CONFIG_DEBUG_BUGVERBOSE
1370 printf("kernel BUG at %s:%u!\n",
1371 bug
->file
, bug
->line
);
1373 printf("kernel BUG at %p!\n", (void *)bug
->bug_addr
);
1377 void excprint(struct pt_regs
*fp
)
1382 printf("cpu 0x%x: ", smp_processor_id());
1383 #endif /* CONFIG_SMP */
1386 printf("Vector: %lx %s at [%lx]\n", fp
->trap
, getvecname(trap
), fp
);
1388 xmon_print_symbol(fp
->nip
, ": ", "\n");
1390 printf(" lr: ", fp
->link
);
1391 xmon_print_symbol(fp
->link
, ": ", "\n");
1393 printf(" sp: %lx\n", fp
->gpr
[1]);
1394 printf(" msr: %lx\n", fp
->msr
);
1396 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600) {
1397 printf(" dar: %lx\n", fp
->dar
);
1399 printf(" dsisr: %lx\n", fp
->dsisr
);
1402 printf(" current = 0x%lx\n", current
);
1404 printf(" paca = 0x%lx\n", get_paca());
1407 printf(" pid = %ld, comm = %s\n",
1408 current
->pid
, current
->comm
);
1415 void prregs(struct pt_regs
*fp
)
1419 struct pt_regs regs
;
1421 if (scanhex(&base
)) {
1422 if (setjmp(bus_error_jmp
) == 0) {
1423 catch_memory_errors
= 1;
1425 regs
= *(struct pt_regs
*)base
;
1429 catch_memory_errors
= 0;
1430 printf("*** Error reading registers from "REG
"\n",
1434 catch_memory_errors
= 0;
1439 if (FULL_REGS(fp
)) {
1440 for (n
= 0; n
< 16; ++n
)
1441 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1442 n
, fp
->gpr
[n
], n
+16, fp
->gpr
[n
+16]);
1444 for (n
= 0; n
< 7; ++n
)
1445 printf("R%.2ld = "REG
" R%.2ld = "REG
"\n",
1446 n
, fp
->gpr
[n
], n
+7, fp
->gpr
[n
+7]);
1449 for (n
= 0; n
< 32; ++n
) {
1450 printf("R%.2d = %.8x%s", n
, fp
->gpr
[n
],
1451 (n
& 3) == 3? "\n": " ");
1452 if (n
== 12 && !FULL_REGS(fp
)) {
1459 xmon_print_symbol(fp
->nip
, " ", "\n");
1461 xmon_print_symbol(fp
->link
, " ", "\n");
1462 printf("msr = "REG
" cr = %.8lx\n", fp
->msr
, fp
->ccr
);
1463 printf("ctr = "REG
" xer = "REG
" trap = %4lx\n",
1464 fp
->ctr
, fp
->xer
, fp
->trap
);
1466 if (trap
== 0x300 || trap
== 0x380 || trap
== 0x600)
1467 printf("dar = "REG
" dsisr = %.8lx\n", fp
->dar
, fp
->dsisr
);
1470 void cacheflush(void)
1473 unsigned long nflush
;
1478 scanhex((void *)&adrs
);
1483 nflush
= (nflush
+ L1_CACHE_BYTES
- 1) / L1_CACHE_BYTES
;
1484 if (setjmp(bus_error_jmp
) == 0) {
1485 catch_memory_errors
= 1;
1489 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1490 cflush((void *) adrs
);
1492 for (; nflush
> 0; --nflush
, adrs
+= L1_CACHE_BYTES
)
1493 cinval((void *) adrs
);
1496 /* wait a little while to see if we get a machine check */
1499 catch_memory_errors
= 0;
1505 unsigned int instrs
[2];
1506 unsigned long (*code
)(void);
1507 unsigned long ret
= -1UL;
1509 unsigned long opd
[3];
1511 opd
[0] = (unsigned long)instrs
;
1514 code
= (unsigned long (*)(void)) opd
;
1516 code
= (unsigned long (*)(void)) instrs
;
1519 /* mfspr r3,n; blr */
1520 instrs
[0] = 0x7c6002a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1521 instrs
[1] = 0x4e800020;
1523 store_inst(instrs
+1);
1525 if (setjmp(bus_error_jmp
) == 0) {
1526 catch_memory_errors
= 1;
1532 /* wait a little while to see if we get a machine check */
1541 write_spr(int n
, unsigned long val
)
1543 unsigned int instrs
[2];
1544 unsigned long (*code
)(unsigned long);
1546 unsigned long opd
[3];
1548 opd
[0] = (unsigned long)instrs
;
1551 code
= (unsigned long (*)(unsigned long)) opd
;
1553 code
= (unsigned long (*)(unsigned long)) instrs
;
1556 instrs
[0] = 0x7c6003a6 + ((n
& 0x1F) << 16) + ((n
& 0x3e0) << 6);
1557 instrs
[1] = 0x4e800020;
1559 store_inst(instrs
+1);
1561 if (setjmp(bus_error_jmp
) == 0) {
1562 catch_memory_errors
= 1;
1568 /* wait a little while to see if we get a machine check */
1574 static unsigned long regno
;
1575 extern char exc_prolog
;
1576 extern char dec_exc
;
1578 void super_regs(void)
1585 unsigned long sp
, toc
;
1586 asm("mr %0,1" : "=r" (sp
) :);
1587 asm("mr %0,2" : "=r" (toc
) :);
1589 printf("msr = "REG
" sprg0= "REG
"\n",
1590 mfmsr(), mfspr(SPRN_SPRG0
));
1591 printf("pvr = "REG
" sprg1= "REG
"\n",
1592 mfspr(SPRN_PVR
), mfspr(SPRN_SPRG1
));
1593 printf("dec = "REG
" sprg2= "REG
"\n",
1594 mfspr(SPRN_DEC
), mfspr(SPRN_SPRG2
));
1595 printf("sp = "REG
" sprg3= "REG
"\n", sp
, mfspr(SPRN_SPRG3
));
1596 printf("toc = "REG
" dar = "REG
"\n", toc
, mfspr(SPRN_DAR
));
1597 #ifdef CONFIG_PPC_ISERIES
1598 if (firmware_has_feature(FW_FEATURE_ISERIES
)) {
1599 struct paca_struct
*ptrPaca
;
1600 struct lppaca
*ptrLpPaca
;
1601 struct ItLpRegSave
*ptrLpRegSave
;
1603 /* Dump out relevant Paca data areas. */
1605 ptrPaca
= get_paca();
1607 printf(" Local Processor Control Area (LpPaca): \n");
1608 ptrLpPaca
= ptrPaca
->lppaca_ptr
;
1609 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1610 ptrLpPaca
->saved_srr0
, ptrLpPaca
->saved_srr1
);
1611 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1612 ptrLpPaca
->saved_gpr3
, ptrLpPaca
->saved_gpr4
);
1613 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca
->saved_gpr5
);
1615 printf(" Local Processor Register Save Area (LpRegSave): \n");
1616 ptrLpRegSave
= ptrPaca
->reg_save_ptr
;
1617 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1618 ptrLpRegSave
->xSPRG0
, ptrLpRegSave
->xSPRG0
);
1619 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1620 ptrLpRegSave
->xSPRG2
, ptrLpRegSave
->xSPRG3
);
1621 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1622 ptrLpRegSave
->xMSR
, ptrLpRegSave
->xNIA
);
1632 val
= read_spr(regno
);
1634 write_spr(regno
, val
);
1637 printf("spr %lx = %lx\n", regno
, read_spr(regno
));
1644 * Stuff for reading and writing memory safely
1647 mread(unsigned long adrs
, void *buf
, int size
)
1653 if (setjmp(bus_error_jmp
) == 0) {
1654 catch_memory_errors
= 1;
1660 *(u16
*)q
= *(u16
*)p
;
1663 *(u32
*)q
= *(u32
*)p
;
1666 *(u64
*)q
= *(u64
*)p
;
1669 for( ; n
< size
; ++n
) {
1675 /* wait a little while to see if we get a machine check */
1679 catch_memory_errors
= 0;
1684 mwrite(unsigned long adrs
, void *buf
, int size
)
1690 if (setjmp(bus_error_jmp
) == 0) {
1691 catch_memory_errors
= 1;
1697 *(u16
*)p
= *(u16
*)q
;
1700 *(u32
*)p
= *(u32
*)q
;
1703 *(u64
*)p
= *(u64
*)q
;
1706 for ( ; n
< size
; ++n
) {
1712 /* wait a little while to see if we get a machine check */
1716 printf("*** Error writing address %x\n", adrs
+ n
);
1718 catch_memory_errors
= 0;
1722 static int fault_type
;
1723 static int fault_except
;
1724 static char *fault_chars
[] = { "--", "**", "##" };
1726 static int handle_fault(struct pt_regs
*regs
)
1728 fault_except
= TRAP(regs
);
1729 switch (TRAP(regs
)) {
1741 longjmp(bus_error_jmp
, 1);
1746 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1749 byterev(unsigned char *val
, int size
)
1755 SWAP(val
[0], val
[1], t
);
1758 SWAP(val
[0], val
[3], t
);
1759 SWAP(val
[1], val
[2], t
);
1761 case 8: /* is there really any use for this? */
1762 SWAP(val
[0], val
[7], t
);
1763 SWAP(val
[1], val
[6], t
);
1764 SWAP(val
[2], val
[5], t
);
1765 SWAP(val
[3], val
[4], t
);
1773 static char *memex_help_string
=
1774 "Memory examine command usage:\n"
1775 "m [addr] [flags] examine/change memory\n"
1776 " addr is optional. will start where left off.\n"
1777 " flags may include chars from this set:\n"
1778 " b modify by bytes (default)\n"
1779 " w modify by words (2 byte)\n"
1780 " l modify by longs (4 byte)\n"
1781 " d modify by doubleword (8 byte)\n"
1782 " r toggle reverse byte order mode\n"
1783 " n do not read memory (for i/o spaces)\n"
1784 " . ok to read (default)\n"
1785 "NOTE: flags are saved as defaults\n"
1788 static char *memex_subcmd_help_string
=
1789 "Memory examine subcommands:\n"
1790 " hexval write this val to current location\n"
1791 " 'string' write chars from string to this location\n"
1792 " ' increment address\n"
1793 " ^ decrement address\n"
1794 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1795 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1796 " ` clear no-read flag\n"
1797 " ; stay at this addr\n"
1798 " v change to byte mode\n"
1799 " w change to word (2 byte) mode\n"
1800 " l change to long (4 byte) mode\n"
1801 " u change to doubleword (8 byte) mode\n"
1802 " m addr change current addr\n"
1803 " n toggle no-read flag\n"
1804 " r toggle byte reverse flag\n"
1805 " < count back up count bytes\n"
1806 " > count skip forward count bytes\n"
1807 " x exit this mode\n"
1813 int cmd
, inc
, i
, nslash
;
1815 unsigned char val
[16];
1817 scanhex((void *)&adrs
);
1820 printf(memex_help_string
);
1826 while ((cmd
= skipbl()) != '\n') {
1828 case 'b': size
= 1; break;
1829 case 'w': size
= 2; break;
1830 case 'l': size
= 4; break;
1831 case 'd': size
= 8; break;
1832 case 'r': brev
= !brev
; break;
1833 case 'n': mnoread
= 1; break;
1834 case '.': mnoread
= 0; break;
1843 n
= mread(adrs
, val
, size
);
1844 printf(REG
"%c", adrs
, brev
? 'r': ' ');
1849 for (i
= 0; i
< n
; ++i
)
1850 printf("%.2x", val
[i
]);
1851 for (; i
< size
; ++i
)
1852 printf("%s", fault_chars
[fault_type
]);
1859 for (i
= 0; i
< size
; ++i
)
1860 val
[i
] = n
>> (i
* 8);
1863 mwrite(adrs
, val
, size
);
1876 else if( n
== '\'' )
1878 for (i
= 0; i
< size
; ++i
)
1879 val
[i
] = n
>> (i
* 8);
1882 mwrite(adrs
, val
, size
);
1919 adrs
-= 1 << nslash
;
1923 adrs
+= 1 << nslash
;
1927 adrs
+= 1 << -nslash
;
1931 adrs
-= 1 << -nslash
;
1934 scanhex((void *)&adrs
);
1953 printf(memex_subcmd_help_string
);
1968 case 'n': c
= '\n'; break;
1969 case 'r': c
= '\r'; break;
1970 case 'b': c
= '\b'; break;
1971 case 't': c
= '\t'; break;
1976 static void xmon_rawdump (unsigned long adrs
, long ndump
)
1979 unsigned char temp
[16];
1981 for (n
= ndump
; n
> 0;) {
1983 nr
= mread(adrs
, temp
, r
);
1985 for (m
= 0; m
< r
; ++m
) {
1987 printf("%.2x", temp
[m
]);
1989 printf("%s", fault_chars
[fault_type
]);
1998 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1999 || ('a' <= (c) && (c) <= 'f') \
2000 || ('A' <= (c) && (c) <= 'F'))
2007 if ((isxdigit(c
) && c
!= 'f' && c
!= 'd') || c
== '\n')
2009 scanhex((void *)&adrs
);
2016 else if (nidump
> MAX_DUMP
)
2018 adrs
+= ppc_inst_dump(adrs
, nidump
, 1);
2020 } else if (c
== 'r') {
2024 xmon_rawdump(adrs
, ndump
);
2031 else if (ndump
> MAX_DUMP
)
2033 prdump(adrs
, ndump
);
2040 prdump(unsigned long adrs
, long ndump
)
2042 long n
, m
, c
, r
, nr
;
2043 unsigned char temp
[16];
2045 for (n
= ndump
; n
> 0;) {
2049 nr
= mread(adrs
, temp
, r
);
2051 for (m
= 0; m
< r
; ++m
) {
2052 if ((m
& (sizeof(long) - 1)) == 0 && m
> 0)
2055 printf("%.2x", temp
[m
]);
2057 printf("%s", fault_chars
[fault_type
]);
2059 for (; m
< 16; ++m
) {
2060 if ((m
& (sizeof(long) - 1)) == 0)
2065 for (m
= 0; m
< r
; ++m
) {
2068 putchar(' ' <= c
&& c
<= '~'? c
: '.');
2081 typedef int (*instruction_dump_func
)(unsigned long inst
, unsigned long addr
);
2084 generic_inst_dump(unsigned long adr
, long count
, int praddr
,
2085 instruction_dump_func dump_func
)
2088 unsigned long first_adr
;
2089 unsigned long inst
, last_inst
= 0;
2090 unsigned char val
[4];
2093 for (first_adr
= adr
; count
> 0; --count
, adr
+= 4) {
2094 nr
= mread(adr
, val
, 4);
2097 const char *x
= fault_chars
[fault_type
];
2098 printf(REG
" %s%s%s%s\n", adr
, x
, x
, x
, x
);
2102 inst
= GETWORD(val
);
2103 if (adr
> first_adr
&& inst
== last_inst
) {
2113 printf(REG
" %.8x", adr
, inst
);
2115 dump_func(inst
, adr
);
2118 return adr
- first_adr
;
2122 ppc_inst_dump(unsigned long adr
, long count
, int praddr
)
2124 return generic_inst_dump(adr
, count
, praddr
, print_insn_powerpc
);
2128 print_address(unsigned long addr
)
2130 xmon_print_symbol(addr
, "\t# ", "");
2135 * Memory operations - move, set, print differences
2137 static unsigned long mdest
; /* destination address */
2138 static unsigned long msrc
; /* source address */
2139 static unsigned long mval
; /* byte value to set memory to */
2140 static unsigned long mcount
; /* # bytes to affect */
2141 static unsigned long mdiffs
; /* max # differences to print */
2146 scanhex((void *)&mdest
);
2147 if( termch
!= '\n' )
2149 scanhex((void *)(cmd
== 's'? &mval
: &msrc
));
2150 if( termch
!= '\n' )
2152 scanhex((void *)&mcount
);
2155 memmove((void *)mdest
, (void *)msrc
, mcount
);
2158 memset((void *)mdest
, mval
, mcount
);
2161 if( termch
!= '\n' )
2163 scanhex((void *)&mdiffs
);
2164 memdiffs((unsigned char *)mdest
, (unsigned char *)msrc
, mcount
, mdiffs
);
2170 memdiffs(unsigned char *p1
, unsigned char *p2
, unsigned nb
, unsigned maxpr
)
2175 for( n
= nb
; n
> 0; --n
)
2176 if( *p1
++ != *p2
++ )
2177 if( ++prt
<= maxpr
)
2178 printf("%.16x %.2x # %.16x %.2x\n", p1
- 1,
2179 p1
[-1], p2
- 1, p2
[-1]);
2181 printf("Total of %d differences\n", prt
);
2184 static unsigned mend
;
2185 static unsigned mask
;
2191 unsigned char val
[4];
2194 scanhex((void *)&mdest
);
2195 if (termch
!= '\n') {
2197 scanhex((void *)&mend
);
2198 if (termch
!= '\n') {
2200 scanhex((void *)&mval
);
2202 if (termch
!= '\n') termch
= 0;
2203 scanhex((void *)&mask
);
2207 for (a
= mdest
; a
< mend
; a
+= 4) {
2208 if (mread(a
, val
, 4) == 4
2209 && ((GETWORD(val
) ^ mval
) & mask
) == 0) {
2210 printf("%.16x: %.16x\n", a
, GETWORD(val
));
2217 static unsigned long mskip
= 0x1000;
2218 static unsigned long mlim
= 0xffffffff;
2228 if (termch
!= '\n') termch
= 0;
2230 if (termch
!= '\n') termch
= 0;
2233 for (a
= mdest
; a
< mlim
; a
+= mskip
) {
2234 ok
= mread(a
, &v
, 1);
2236 printf("%.8x .. ", a
);
2237 } else if (!ok
&& ook
)
2238 printf("%.8x\n", a
- mskip
);
2244 printf("%.8x\n", a
- mskip
);
2249 unsigned long args
[8];
2252 typedef unsigned long (*callfunc_t
)(unsigned long, unsigned long,
2253 unsigned long, unsigned long, unsigned long,
2254 unsigned long, unsigned long, unsigned long);
2257 if (!scanhex(&adrs
))
2261 for (i
= 0; i
< 8; ++i
)
2263 for (i
= 0; i
< 8; ++i
) {
2264 if (!scanhex(&args
[i
]) || termch
== '\n')
2268 func
= (callfunc_t
) adrs
;
2270 if (setjmp(bus_error_jmp
) == 0) {
2271 catch_memory_errors
= 1;
2273 ret
= func(args
[0], args
[1], args
[2], args
[3],
2274 args
[4], args
[5], args
[6], args
[7]);
2276 printf("return value is %x\n", ret
);
2278 printf("*** %x exception occurred\n", fault_except
);
2280 catch_memory_errors
= 0;
2283 /* Input scanning routines */
2294 while( c
== ' ' || c
== '\t' )
2300 static char *regnames
[N_PTREGS
] = {
2301 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2302 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2303 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2304 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2305 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2311 "trap", "dar", "dsisr", "res"
2315 scanhex(unsigned long *vp
)
2322 /* parse register name */
2326 for (i
= 0; i
< sizeof(regname
) - 1; ++i
) {
2335 for (i
= 0; i
< N_PTREGS
; ++i
) {
2336 if (strcmp(regnames
[i
], regname
) == 0) {
2337 if (xmon_regs
== NULL
) {
2338 printf("regs not available\n");
2341 *vp
= ((unsigned long *)xmon_regs
)[i
];
2345 printf("invalid register name '%%%s'\n", regname
);
2349 /* skip leading "0x" if any */
2363 } else if (c
== '$') {
2365 for (i
=0; i
<63; i
++) {
2375 if (setjmp(bus_error_jmp
) == 0) {
2376 catch_memory_errors
= 1;
2378 *vp
= kallsyms_lookup_name(tmpstr
);
2381 catch_memory_errors
= 0;
2383 printf("unknown symbol '%s'\n", tmpstr
);
2418 if( '0' <= c
&& c
<= '9' )
2420 if( 'A' <= c
&& c
<= 'F' )
2421 return c
- ('A' - 10);
2422 if( 'a' <= c
&& c
<= 'f' )
2423 return c
- ('a' - 10);
2428 getstring(char *s
, int size
)
2439 } while( c
!= ' ' && c
!= '\t' && c
!= '\n' );
2444 static char line
[256];
2445 static char *lineptr
;
2456 if (lineptr
== NULL
|| *lineptr
== 0) {
2457 if (xmon_gets(line
, sizeof(line
)) == NULL
) {
2467 take_input(char *str
)
2476 int type
= inchar();
2478 static char tmp
[64];
2483 xmon_print_symbol(addr
, ": ", "\n");
2488 if (setjmp(bus_error_jmp
) == 0) {
2489 catch_memory_errors
= 1;
2491 addr
= kallsyms_lookup_name(tmp
);
2493 printf("%s: %lx\n", tmp
, addr
);
2495 printf("Symbol '%s' not found.\n", tmp
);
2498 catch_memory_errors
= 0;
2505 /* Print an address in numeric and symbolic form (if possible) */
2506 static void xmon_print_symbol(unsigned long address
, const char *mid
,
2510 const char *name
= NULL
;
2511 unsigned long offset
, size
;
2513 printf(REG
, address
);
2514 if (setjmp(bus_error_jmp
) == 0) {
2515 catch_memory_errors
= 1;
2517 name
= kallsyms_lookup(address
, &size
, &offset
, &modname
,
2520 /* wait a little while to see if we get a machine check */
2524 catch_memory_errors
= 0;
2527 printf("%s%s+%#lx/%#lx", mid
, name
, offset
, size
);
2529 printf(" [%s]", modname
);
2531 printf("%s", after
);
2535 static void dump_slb(void)
2538 unsigned long esid
,vsid
,valid
;
2541 printf("SLB contents of cpu %x\n", smp_processor_id());
2543 for (i
= 0; i
< mmu_slb_size
; i
++) {
2544 asm volatile("slbmfee %0,%1" : "=r" (esid
) : "r" (i
));
2545 asm volatile("slbmfev %0,%1" : "=r" (vsid
) : "r" (i
));
2546 valid
= (esid
& SLB_ESID_V
);
2547 if (valid
| esid
| vsid
) {
2548 printf("%02d %016lx %016lx", i
, esid
, vsid
);
2550 llp
= vsid
& SLB_VSID_LLP
;
2551 if (vsid
& SLB_VSID_B_1T
) {
2552 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2554 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT_1T
,
2557 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2559 (vsid
& ~SLB_VSID_B
) >> SLB_VSID_SHIFT
,
2568 static void dump_stab(void)
2571 unsigned long *tmp
= (unsigned long *)get_paca()->stab_addr
;
2573 printf("Segment table contents of cpu %x\n", smp_processor_id());
2575 for (i
= 0; i
< PAGE_SIZE
/16; i
++) {
2582 printf("%03d %016lx ", i
, a
);
2583 printf("%016lx\n", b
);
2588 void dump_segments(void)
2590 if (cpu_has_feature(CPU_FTR_SLB
))
2597 #ifdef CONFIG_PPC_STD_MMU_32
2598 void dump_segments(void)
2603 for (i
= 0; i
< 16; ++i
)
2604 printf(" %x", mfsrin(i
));
2610 static void dump_tlb_44x(void)
2614 for (i
= 0; i
< PPC44x_TLB_SIZE
; i
++) {
2615 unsigned long w0
,w1
,w2
;
2616 asm volatile("tlbre %0,%1,0" : "=r" (w0
) : "r" (i
));
2617 asm volatile("tlbre %0,%1,1" : "=r" (w1
) : "r" (i
));
2618 asm volatile("tlbre %0,%1,2" : "=r" (w2
) : "r" (i
));
2619 printf("[%02x] %08x %08x %08x ", i
, w0
, w1
, w2
);
2620 if (w0
& PPC44x_TLB_VALID
) {
2621 printf("V %08x -> %01x%08x %c%c%c%c%c",
2622 w0
& PPC44x_TLB_EPN_MASK
,
2623 w1
& PPC44x_TLB_ERPN_MASK
,
2624 w1
& PPC44x_TLB_RPN_MASK
,
2625 (w2
& PPC44x_TLB_W
) ? 'W' : 'w',
2626 (w2
& PPC44x_TLB_I
) ? 'I' : 'i',
2627 (w2
& PPC44x_TLB_M
) ? 'M' : 'm',
2628 (w2
& PPC44x_TLB_G
) ? 'G' : 'g',
2629 (w2
& PPC44x_TLB_E
) ? 'E' : 'e');
2634 #endif /* CONFIG_44x */
2635 void xmon_init(int enable
)
2637 #ifdef CONFIG_PPC_ISERIES
2638 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2643 __debugger_ipi
= xmon_ipi
;
2644 __debugger_bpt
= xmon_bpt
;
2645 __debugger_sstep
= xmon_sstep
;
2646 __debugger_iabr_match
= xmon_iabr_match
;
2647 __debugger_dabr_match
= xmon_dabr_match
;
2648 __debugger_fault_handler
= xmon_fault_handler
;
2651 __debugger_ipi
= NULL
;
2652 __debugger_bpt
= NULL
;
2653 __debugger_sstep
= NULL
;
2654 __debugger_iabr_match
= NULL
;
2655 __debugger_dabr_match
= NULL
;
2656 __debugger_fault_handler
= NULL
;
2661 #ifdef CONFIG_MAGIC_SYSRQ
2662 static void sysrq_handle_xmon(int key
, struct tty_struct
*tty
)
2664 /* ensure xmon is enabled */
2666 debugger(get_irq_regs());
2669 static struct sysrq_key_op sysrq_xmon_op
=
2671 .handler
= sysrq_handle_xmon
,
2673 .action_msg
= "Entering xmon",
2676 static int __init
setup_xmon_sysrq(void)
2678 #ifdef CONFIG_PPC_ISERIES
2679 if (firmware_has_feature(FW_FEATURE_ISERIES
))
2682 register_sysrq_key('x', &sysrq_xmon_op
);
2685 __initcall(setup_xmon_sysrq
);
2686 #endif /* CONFIG_MAGIC_SYSRQ */
2688 static int __initdata xmon_early
, xmon_off
;
2690 static int __init
early_parse_xmon(char *p
)
2692 if (!p
|| strncmp(p
, "early", 5) == 0) {
2693 /* just "xmon" is equivalent to "xmon=early" */
2696 } else if (strncmp(p
, "on", 2) == 0)
2698 else if (strncmp(p
, "off", 3) == 0)
2700 else if (strncmp(p
, "nobt", 4) == 0)
2701 xmon_no_auto_backtrace
= 1;
2707 early_param("xmon", early_parse_xmon
);
2709 void __init
xmon_setup(void)
2711 #ifdef CONFIG_XMON_DEFAULT
2719 #ifdef CONFIG_SPU_BASE
2723 u64 saved_mfc_sr1_RW
;
2724 u32 saved_spu_runcntl_RW
;
2725 unsigned long dump_addr
;
2729 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2731 static struct spu_info spu_info
[XMON_NUM_SPUS
];
2733 void xmon_register_spus(struct list_head
*list
)
2737 list_for_each_entry(spu
, list
, full_list
) {
2738 if (spu
->number
>= XMON_NUM_SPUS
) {
2743 spu_info
[spu
->number
].spu
= spu
;
2744 spu_info
[spu
->number
].stopped_ok
= 0;
2745 spu_info
[spu
->number
].dump_addr
= (unsigned long)
2746 spu_info
[spu
->number
].spu
->local_store
;
2750 static void stop_spus(void)
2756 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2757 if (!spu_info
[i
].spu
)
2760 if (setjmp(bus_error_jmp
) == 0) {
2761 catch_memory_errors
= 1;
2764 spu
= spu_info
[i
].spu
;
2766 spu_info
[i
].saved_spu_runcntl_RW
=
2767 in_be32(&spu
->problem
->spu_runcntl_RW
);
2769 tmp
= spu_mfc_sr1_get(spu
);
2770 spu_info
[i
].saved_mfc_sr1_RW
= tmp
;
2772 tmp
&= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK
;
2773 spu_mfc_sr1_set(spu
, tmp
);
2778 spu_info
[i
].stopped_ok
= 1;
2780 printf("Stopped spu %.2d (was %s)\n", i
,
2781 spu_info
[i
].saved_spu_runcntl_RW
?
2782 "running" : "stopped");
2784 catch_memory_errors
= 0;
2785 printf("*** Error stopping spu %.2d\n", i
);
2787 catch_memory_errors
= 0;
2791 static void restart_spus(void)
2796 for (i
= 0; i
< XMON_NUM_SPUS
; i
++) {
2797 if (!spu_info
[i
].spu
)
2800 if (!spu_info
[i
].stopped_ok
) {
2801 printf("*** Error, spu %d was not successfully stopped"
2802 ", not restarting\n", i
);
2806 if (setjmp(bus_error_jmp
) == 0) {
2807 catch_memory_errors
= 1;
2810 spu
= spu_info
[i
].spu
;
2811 spu_mfc_sr1_set(spu
, spu_info
[i
].saved_mfc_sr1_RW
);
2812 out_be32(&spu
->problem
->spu_runcntl_RW
,
2813 spu_info
[i
].saved_spu_runcntl_RW
);
2818 printf("Restarted spu %.2d\n", i
);
2820 catch_memory_errors
= 0;
2821 printf("*** Error restarting spu %.2d\n", i
);
2823 catch_memory_errors
= 0;
2827 #define DUMP_WIDTH 23
2828 #define DUMP_VALUE(format, field, value) \
2830 if (setjmp(bus_error_jmp) == 0) { \
2831 catch_memory_errors = 1; \
2833 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2838 catch_memory_errors = 0; \
2839 printf(" %-*s = *** Error reading field.\n", \
2840 DUMP_WIDTH, #field); \
2842 catch_memory_errors = 0; \
2845 #define DUMP_FIELD(obj, format, field) \
2846 DUMP_VALUE(format, field, obj->field)
2848 static void dump_spu_fields(struct spu
*spu
)
2850 printf("Dumping spu fields at address %p:\n", spu
);
2852 DUMP_FIELD(spu
, "0x%x", number
);
2853 DUMP_FIELD(spu
, "%s", name
);
2854 DUMP_FIELD(spu
, "0x%lx", local_store_phys
);
2855 DUMP_FIELD(spu
, "0x%p", local_store
);
2856 DUMP_FIELD(spu
, "0x%lx", ls_size
);
2857 DUMP_FIELD(spu
, "0x%x", node
);
2858 DUMP_FIELD(spu
, "0x%lx", flags
);
2859 DUMP_FIELD(spu
, "0x%lx", dar
);
2860 DUMP_FIELD(spu
, "0x%lx", dsisr
);
2861 DUMP_FIELD(spu
, "%d", class_0_pending
);
2862 DUMP_FIELD(spu
, "0x%lx", irqs
[0]);
2863 DUMP_FIELD(spu
, "0x%lx", irqs
[1]);
2864 DUMP_FIELD(spu
, "0x%lx", irqs
[2]);
2865 DUMP_FIELD(spu
, "0x%x", slb_replace
);
2866 DUMP_FIELD(spu
, "%d", pid
);
2867 DUMP_FIELD(spu
, "0x%p", mm
);
2868 DUMP_FIELD(spu
, "0x%p", ctx
);
2869 DUMP_FIELD(spu
, "0x%p", rq
);
2870 DUMP_FIELD(spu
, "0x%p", timestamp
);
2871 DUMP_FIELD(spu
, "0x%lx", problem_phys
);
2872 DUMP_FIELD(spu
, "0x%p", problem
);
2873 DUMP_VALUE("0x%x", problem
->spu_runcntl_RW
,
2874 in_be32(&spu
->problem
->spu_runcntl_RW
));
2875 DUMP_VALUE("0x%x", problem
->spu_status_R
,
2876 in_be32(&spu
->problem
->spu_status_R
));
2877 DUMP_VALUE("0x%x", problem
->spu_npc_RW
,
2878 in_be32(&spu
->problem
->spu_npc_RW
));
2879 DUMP_FIELD(spu
, "0x%p", priv2
);
2880 DUMP_FIELD(spu
, "0x%p", pdata
);
2884 spu_inst_dump(unsigned long adr
, long count
, int praddr
)
2886 return generic_inst_dump(adr
, count
, praddr
, print_insn_spu
);
2889 static void dump_spu_ls(unsigned long num
, int subcmd
)
2891 unsigned long offset
, addr
, ls_addr
;
2893 if (setjmp(bus_error_jmp
) == 0) {
2894 catch_memory_errors
= 1;
2896 ls_addr
= (unsigned long)spu_info
[num
].spu
->local_store
;
2900 catch_memory_errors
= 0;
2901 printf("*** Error: accessing spu info for spu %d\n", num
);
2904 catch_memory_errors
= 0;
2906 if (scanhex(&offset
))
2907 addr
= ls_addr
+ offset
;
2909 addr
= spu_info
[num
].dump_addr
;
2911 if (addr
>= ls_addr
+ LS_SIZE
) {
2912 printf("*** Error: address outside of local store\n");
2918 addr
+= spu_inst_dump(addr
, 16, 1);
2928 spu_info
[num
].dump_addr
= addr
;
2931 static int do_spu_cmd(void)
2933 static unsigned long num
= 0;
2934 int cmd
, subcmd
= 0;
2946 if (isxdigit(subcmd
) || subcmd
== '\n')
2950 if (num
>= XMON_NUM_SPUS
|| !spu_info
[num
].spu
) {
2951 printf("*** Error: invalid spu number\n");
2957 dump_spu_fields(spu_info
[num
].spu
);
2960 dump_spu_ls(num
, subcmd
);
2971 #else /* ! CONFIG_SPU_BASE */
2972 static int do_spu_cmd(void)