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)
1356 const struct bug_entry *bug;
1359 if (regs->msr & MSR_PR)
1360 return; /* not in kernel */
1361 addr = regs->nip; /* address of trap instruction */
1362 if (addr < PAGE_OFFSET)
1364 bug = find_bug(regs->nip);
1367 if (is_warning_bug(bug))
1370 #ifdef CONFIG_DEBUG_BUGVERBOSE
1371 printf("kernel BUG at %s:%u!\n",
1372 bug->file, bug->line);
1374 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1378 static void excprint(struct pt_regs *fp)
1383 printf("cpu 0x%x: ", smp_processor_id());
1384 #endif /* CONFIG_SMP */
1387 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1389 xmon_print_symbol(fp->nip, ": ", "\n");
1391 printf(" lr: ", fp->link);
1392 xmon_print_symbol(fp->link, ": ", "\n");
1394 printf(" sp: %lx\n", fp->gpr[1]);
1395 printf(" msr: %lx\n", fp->msr);
1397 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1398 printf(" dar: %lx\n", fp->dar);
1400 printf(" dsisr: %lx\n", fp->dsisr);
1403 printf(" current = 0x%lx\n", current);
1405 printf(" paca = 0x%lx\n", get_paca());
1408 printf(" pid = %ld, comm = %s\n",
1409 current->pid, current->comm);
1416 static void prregs(struct pt_regs *fp)
1420 struct pt_regs regs;
1422 if (scanhex(&base)) {
1423 if (setjmp(bus_error_jmp) == 0) {
1424 catch_memory_errors = 1;
1426 regs = *(struct pt_regs *)base;
1430 catch_memory_errors = 0;
1431 printf("*** Error reading registers from "REG"\n",
1435 catch_memory_errors = 0;
1440 if (FULL_REGS(fp)) {
1441 for (n = 0; n < 16; ++n)
1442 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1443 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1445 for (n = 0; n < 7; ++n)
1446 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1447 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1450 for (n = 0; n < 32; ++n) {
1451 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1452 (n & 3) == 3? "\n": " ");
1453 if (n == 12 && !FULL_REGS(fp)) {
1460 xmon_print_symbol(fp->nip, " ", "\n");
1462 xmon_print_symbol(fp->link, " ", "\n");
1463 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1464 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1465 fp->ctr, fp->xer, fp->trap);
1467 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1468 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1471 static void cacheflush(void)
1474 unsigned long nflush;
1479 scanhex((void *)&adrs);
1484 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1485 if (setjmp(bus_error_jmp) == 0) {
1486 catch_memory_errors = 1;
1490 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1491 cflush((void *) adrs);
1493 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1494 cinval((void *) adrs);
1497 /* wait a little while to see if we get a machine check */
1500 catch_memory_errors = 0;
1503 static unsigned long
1506 unsigned int instrs[2];
1507 unsigned long (*code)(void);
1508 unsigned long ret = -1UL;
1510 unsigned long opd[3];
1512 opd[0] = (unsigned long)instrs;
1515 code = (unsigned long (*)(void)) opd;
1517 code = (unsigned long (*)(void)) instrs;
1520 /* mfspr r3,n; blr */
1521 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1522 instrs[1] = 0x4e800020;
1524 store_inst(instrs+1);
1526 if (setjmp(bus_error_jmp) == 0) {
1527 catch_memory_errors = 1;
1533 /* wait a little while to see if we get a machine check */
1542 write_spr(int n, unsigned long val)
1544 unsigned int instrs[2];
1545 unsigned long (*code)(unsigned long);
1547 unsigned long opd[3];
1549 opd[0] = (unsigned long)instrs;
1552 code = (unsigned long (*)(unsigned long)) opd;
1554 code = (unsigned long (*)(unsigned long)) instrs;
1557 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1558 instrs[1] = 0x4e800020;
1560 store_inst(instrs+1);
1562 if (setjmp(bus_error_jmp) == 0) {
1563 catch_memory_errors = 1;
1569 /* wait a little while to see if we get a machine check */
1575 static unsigned long regno;
1576 extern char exc_prolog;
1577 extern char dec_exc;
1579 static void super_regs(void)
1586 unsigned long sp, toc;
1587 asm("mr %0,1" : "=r" (sp) :);
1588 asm("mr %0,2" : "=r" (toc) :);
1590 printf("msr = "REG" sprg0= "REG"\n",
1591 mfmsr(), mfspr(SPRN_SPRG0));
1592 printf("pvr = "REG" sprg1= "REG"\n",
1593 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1594 printf("dec = "REG" sprg2= "REG"\n",
1595 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1596 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1597 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1598 #ifdef CONFIG_PPC_ISERIES
1599 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1600 struct paca_struct *ptrPaca;
1601 struct lppaca *ptrLpPaca;
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);
1623 val = read_spr(regno);
1625 write_spr(regno, val);
1628 printf("spr %lx = %lx\n", regno, read_spr(regno));
1635 * Stuff for reading and writing memory safely
1638 mread(unsigned long adrs, void *buf, int size)
1644 if (setjmp(bus_error_jmp) == 0) {
1645 catch_memory_errors = 1;
1651 *(u16 *)q = *(u16 *)p;
1654 *(u32 *)q = *(u32 *)p;
1657 *(u64 *)q = *(u64 *)p;
1660 for( ; n < size; ++n) {
1666 /* wait a little while to see if we get a machine check */
1670 catch_memory_errors = 0;
1675 mwrite(unsigned long adrs, void *buf, int size)
1681 if (setjmp(bus_error_jmp) == 0) {
1682 catch_memory_errors = 1;
1688 *(u16 *)p = *(u16 *)q;
1691 *(u32 *)p = *(u32 *)q;
1694 *(u64 *)p = *(u64 *)q;
1697 for ( ; n < size; ++n) {
1703 /* wait a little while to see if we get a machine check */
1707 printf("*** Error writing address %x\n", adrs + n);
1709 catch_memory_errors = 0;
1713 static int fault_type;
1714 static int fault_except;
1715 static char *fault_chars[] = { "--", "**", "##" };
1717 static int handle_fault(struct pt_regs *regs)
1719 fault_except = TRAP(regs);
1720 switch (TRAP(regs)) {
1732 longjmp(bus_error_jmp, 1);
1737 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1740 byterev(unsigned char *val, int size)
1746 SWAP(val[0], val[1], t);
1749 SWAP(val[0], val[3], t);
1750 SWAP(val[1], val[2], t);
1752 case 8: /* is there really any use for this? */
1753 SWAP(val[0], val[7], t);
1754 SWAP(val[1], val[6], t);
1755 SWAP(val[2], val[5], t);
1756 SWAP(val[3], val[4], t);
1764 static char *memex_help_string =
1765 "Memory examine command usage:\n"
1766 "m [addr] [flags] examine/change memory\n"
1767 " addr is optional. will start where left off.\n"
1768 " flags may include chars from this set:\n"
1769 " b modify by bytes (default)\n"
1770 " w modify by words (2 byte)\n"
1771 " l modify by longs (4 byte)\n"
1772 " d modify by doubleword (8 byte)\n"
1773 " r toggle reverse byte order mode\n"
1774 " n do not read memory (for i/o spaces)\n"
1775 " . ok to read (default)\n"
1776 "NOTE: flags are saved as defaults\n"
1779 static char *memex_subcmd_help_string =
1780 "Memory examine subcommands:\n"
1781 " hexval write this val to current location\n"
1782 " 'string' write chars from string to this location\n"
1783 " ' increment address\n"
1784 " ^ decrement address\n"
1785 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1786 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1787 " ` clear no-read flag\n"
1788 " ; stay at this addr\n"
1789 " v change to byte mode\n"
1790 " w change to word (2 byte) mode\n"
1791 " l change to long (4 byte) mode\n"
1792 " u change to doubleword (8 byte) mode\n"
1793 " m addr change current addr\n"
1794 " n toggle no-read flag\n"
1795 " r toggle byte reverse flag\n"
1796 " < count back up count bytes\n"
1797 " > count skip forward count bytes\n"
1798 " x exit this mode\n"
1804 int cmd, inc, i, nslash;
1806 unsigned char val[16];
1808 scanhex((void *)&adrs);
1811 printf(memex_help_string);
1817 while ((cmd = skipbl()) != '\n') {
1819 case 'b': size = 1; break;
1820 case 'w': size = 2; break;
1821 case 'l': size = 4; break;
1822 case 'd': size = 8; break;
1823 case 'r': brev = !brev; break;
1824 case 'n': mnoread = 1; break;
1825 case '.': mnoread = 0; break;
1834 n = mread(adrs, val, size);
1835 printf(REG"%c", adrs, brev? 'r': ' ');
1840 for (i = 0; i < n; ++i)
1841 printf("%.2x", val[i]);
1842 for (; i < size; ++i)
1843 printf("%s", fault_chars[fault_type]);
1850 for (i = 0; i < size; ++i)
1851 val[i] = n >> (i * 8);
1854 mwrite(adrs, val, size);
1867 else if( n == '\'' )
1869 for (i = 0; i < size; ++i)
1870 val[i] = n >> (i * 8);
1873 mwrite(adrs, val, size);
1910 adrs -= 1 << nslash;
1914 adrs += 1 << nslash;
1918 adrs += 1 << -nslash;
1922 adrs -= 1 << -nslash;
1925 scanhex((void *)&adrs);
1944 printf(memex_subcmd_help_string);
1959 case 'n': c = '\n'; break;
1960 case 'r': c = '\r'; break;
1961 case 'b': c = '\b'; break;
1962 case 't': c = '\t'; break;
1967 static void xmon_rawdump (unsigned long adrs, long ndump)
1970 unsigned char temp[16];
1972 for (n = ndump; n > 0;) {
1974 nr = mread(adrs, temp, r);
1976 for (m = 0; m < r; ++m) {
1978 printf("%.2x", temp[m]);
1980 printf("%s", fault_chars[fault_type]);
1989 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1990 || ('a' <= (c) && (c) <= 'f') \
1991 || ('A' <= (c) && (c) <= 'F'))
1998 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2000 scanhex((void *)&adrs);
2007 else if (nidump > MAX_DUMP)
2009 adrs += ppc_inst_dump(adrs, nidump, 1);
2011 } else if (c == 'r') {
2015 xmon_rawdump(adrs, ndump);
2022 else if (ndump > MAX_DUMP)
2024 prdump(adrs, ndump);
2031 prdump(unsigned long adrs, long ndump)
2033 long n, m, c, r, nr;
2034 unsigned char temp[16];
2036 for (n = ndump; n > 0;) {
2040 nr = mread(adrs, temp, r);
2042 for (m = 0; m < r; ++m) {
2043 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2046 printf("%.2x", temp[m]);
2048 printf("%s", fault_chars[fault_type]);
2050 for (; m < 16; ++m) {
2051 if ((m & (sizeof(long) - 1)) == 0)
2056 for (m = 0; m < r; ++m) {
2059 putchar(' ' <= c && c <= '~'? c: '.');
2072 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2075 generic_inst_dump(unsigned long adr, long count, int praddr,
2076 instruction_dump_func dump_func)
2079 unsigned long first_adr;
2080 unsigned long inst, last_inst = 0;
2081 unsigned char val[4];
2084 for (first_adr = adr; count > 0; --count, adr += 4) {
2085 nr = mread(adr, val, 4);
2088 const char *x = fault_chars[fault_type];
2089 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2093 inst = GETWORD(val);
2094 if (adr > first_adr && inst == last_inst) {
2104 printf(REG" %.8x", adr, inst);
2106 dump_func(inst, adr);
2109 return adr - first_adr;
2113 ppc_inst_dump(unsigned long adr, long count, int praddr)
2115 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2119 print_address(unsigned long addr)
2121 xmon_print_symbol(addr, "\t# ", "");
2126 * Memory operations - move, set, print differences
2128 static unsigned long mdest; /* destination address */
2129 static unsigned long msrc; /* source address */
2130 static unsigned long mval; /* byte value to set memory to */
2131 static unsigned long mcount; /* # bytes to affect */
2132 static unsigned long mdiffs; /* max # differences to print */
2137 scanhex((void *)&mdest);
2138 if( termch != '\n' )
2140 scanhex((void *)(cmd == 's'? &mval: &msrc));
2141 if( termch != '\n' )
2143 scanhex((void *)&mcount);
2146 memmove((void *)mdest, (void *)msrc, mcount);
2149 memset((void *)mdest, mval, mcount);
2152 if( termch != '\n' )
2154 scanhex((void *)&mdiffs);
2155 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2161 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2166 for( n = nb; n > 0; --n )
2167 if( *p1++ != *p2++ )
2168 if( ++prt <= maxpr )
2169 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2170 p1[-1], p2 - 1, p2[-1]);
2172 printf("Total of %d differences\n", prt);
2175 static unsigned mend;
2176 static unsigned mask;
2182 unsigned char val[4];
2185 scanhex((void *)&mdest);
2186 if (termch != '\n') {
2188 scanhex((void *)&mend);
2189 if (termch != '\n') {
2191 scanhex((void *)&mval);
2193 if (termch != '\n') termch = 0;
2194 scanhex((void *)&mask);
2198 for (a = mdest; a < mend; a += 4) {
2199 if (mread(a, val, 4) == 4
2200 && ((GETWORD(val) ^ mval) & mask) == 0) {
2201 printf("%.16x: %.16x\n", a, GETWORD(val));
2208 static unsigned long mskip = 0x1000;
2209 static unsigned long mlim = 0xffffffff;
2219 if (termch != '\n') termch = 0;
2221 if (termch != '\n') termch = 0;
2224 for (a = mdest; a < mlim; a += mskip) {
2225 ok = mread(a, &v, 1);
2227 printf("%.8x .. ", a);
2228 } else if (!ok && ook)
2229 printf("%.8x\n", a - mskip);
2235 printf("%.8x\n", a - mskip);
2238 static void proccall(void)
2240 unsigned long args[8];
2243 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2244 unsigned long, unsigned long, unsigned long,
2245 unsigned long, unsigned long, unsigned long);
2248 if (!scanhex(&adrs))
2252 for (i = 0; i < 8; ++i)
2254 for (i = 0; i < 8; ++i) {
2255 if (!scanhex(&args[i]) || termch == '\n')
2259 func = (callfunc_t) adrs;
2261 if (setjmp(bus_error_jmp) == 0) {
2262 catch_memory_errors = 1;
2264 ret = func(args[0], args[1], args[2], args[3],
2265 args[4], args[5], args[6], args[7]);
2267 printf("return value is %x\n", ret);
2269 printf("*** %x exception occurred\n", fault_except);
2271 catch_memory_errors = 0;
2274 /* Input scanning routines */
2285 while( c == ' ' || c == '\t' )
2291 static char *regnames[N_PTREGS] = {
2292 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2293 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2294 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2295 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2296 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2302 "trap", "dar", "dsisr", "res"
2306 scanhex(unsigned long *vp)
2313 /* parse register name */
2317 for (i = 0; i < sizeof(regname) - 1; ++i) {
2326 for (i = 0; i < N_PTREGS; ++i) {
2327 if (strcmp(regnames[i], regname) == 0) {
2328 if (xmon_regs == NULL) {
2329 printf("regs not available\n");
2332 *vp = ((unsigned long *)xmon_regs)[i];
2336 printf("invalid register name '%%%s'\n", regname);
2340 /* skip leading "0x" if any */
2354 } else if (c == '$') {
2356 for (i=0; i<63; i++) {
2366 if (setjmp(bus_error_jmp) == 0) {
2367 catch_memory_errors = 1;
2369 *vp = kallsyms_lookup_name(tmpstr);
2372 catch_memory_errors = 0;
2374 printf("unknown symbol '%s'\n", tmpstr);
2407 static int hexdigit(int c)
2409 if( '0' <= c && c <= '9' )
2411 if( 'A' <= c && c <= 'F' )
2412 return c - ('A' - 10);
2413 if( 'a' <= c && c <= 'f' )
2414 return c - ('a' - 10);
2419 getstring(char *s, int size)
2430 } while( c != ' ' && c != '\t' && c != '\n' );
2435 static char line[256];
2436 static char *lineptr;
2447 if (lineptr == NULL || *lineptr == 0) {
2448 if (xmon_gets(line, sizeof(line)) == NULL) {
2458 take_input(char *str)
2467 int type = inchar();
2469 static char tmp[64];
2474 xmon_print_symbol(addr, ": ", "\n");
2479 if (setjmp(bus_error_jmp) == 0) {
2480 catch_memory_errors = 1;
2482 addr = kallsyms_lookup_name(tmp);
2484 printf("%s: %lx\n", tmp, addr);
2486 printf("Symbol '%s' not found.\n", tmp);
2489 catch_memory_errors = 0;
2496 /* Print an address in numeric and symbolic form (if possible) */
2497 static void xmon_print_symbol(unsigned long address, const char *mid,
2501 const char *name = NULL;
2502 unsigned long offset, size;
2504 printf(REG, address);
2505 if (setjmp(bus_error_jmp) == 0) {
2506 catch_memory_errors = 1;
2508 name = kallsyms_lookup(address, &size, &offset, &modname,
2511 /* wait a little while to see if we get a machine check */
2515 catch_memory_errors = 0;
2518 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2520 printf(" [%s]", modname);
2522 printf("%s", after);
2526 static void dump_slb(void)
2529 unsigned long esid,vsid,valid;
2532 printf("SLB contents of cpu %x\n", smp_processor_id());
2534 for (i = 0; i < mmu_slb_size; i++) {
2535 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2536 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2537 valid = (esid & SLB_ESID_V);
2538 if (valid | esid | vsid) {
2539 printf("%02d %016lx %016lx", i, esid, vsid);
2541 llp = vsid & SLB_VSID_LLP;
2542 if (vsid & SLB_VSID_B_1T) {
2543 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2545 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2548 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2550 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2559 static void dump_stab(void)
2562 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2564 printf("Segment table contents of cpu %x\n", smp_processor_id());
2566 for (i = 0; i < PAGE_SIZE/16; i++) {
2573 printf("%03d %016lx ", i, a);
2574 printf("%016lx\n", b);
2579 void dump_segments(void)
2581 if (cpu_has_feature(CPU_FTR_SLB))
2588 #ifdef CONFIG_PPC_STD_MMU_32
2589 void dump_segments(void)
2594 for (i = 0; i < 16; ++i)
2595 printf(" %x", mfsrin(i));
2601 static void dump_tlb_44x(void)
2605 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2606 unsigned long w0,w1,w2;
2607 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2608 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2609 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2610 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2611 if (w0 & PPC44x_TLB_VALID) {
2612 printf("V %08x -> %01x%08x %c%c%c%c%c",
2613 w0 & PPC44x_TLB_EPN_MASK,
2614 w1 & PPC44x_TLB_ERPN_MASK,
2615 w1 & PPC44x_TLB_RPN_MASK,
2616 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2617 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2618 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2619 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2620 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2625 #endif /* CONFIG_44x */
2627 static void xmon_init(int enable)
2629 #ifdef CONFIG_PPC_ISERIES
2630 if (firmware_has_feature(FW_FEATURE_ISERIES))
2635 __debugger_ipi = xmon_ipi;
2636 __debugger_bpt = xmon_bpt;
2637 __debugger_sstep = xmon_sstep;
2638 __debugger_iabr_match = xmon_iabr_match;
2639 __debugger_dabr_match = xmon_dabr_match;
2640 __debugger_fault_handler = xmon_fault_handler;
2643 __debugger_ipi = NULL;
2644 __debugger_bpt = NULL;
2645 __debugger_sstep = NULL;
2646 __debugger_iabr_match = NULL;
2647 __debugger_dabr_match = NULL;
2648 __debugger_fault_handler = NULL;
2653 #ifdef CONFIG_MAGIC_SYSRQ
2654 static void sysrq_handle_xmon(int key, struct tty_struct *tty)
2656 /* ensure xmon is enabled */
2658 debugger(get_irq_regs());
2661 static struct sysrq_key_op sysrq_xmon_op =
2663 .handler = sysrq_handle_xmon,
2665 .action_msg = "Entering xmon",
2668 static int __init setup_xmon_sysrq(void)
2670 #ifdef CONFIG_PPC_ISERIES
2671 if (firmware_has_feature(FW_FEATURE_ISERIES))
2674 register_sysrq_key('x', &sysrq_xmon_op);
2677 __initcall(setup_xmon_sysrq);
2678 #endif /* CONFIG_MAGIC_SYSRQ */
2680 static int __initdata xmon_early, xmon_off;
2682 static int __init early_parse_xmon(char *p)
2684 if (!p || strncmp(p, "early", 5) == 0) {
2685 /* just "xmon" is equivalent to "xmon=early" */
2688 } else if (strncmp(p, "on", 2) == 0)
2690 else if (strncmp(p, "off", 3) == 0)
2692 else if (strncmp(p, "nobt", 4) == 0)
2693 xmon_no_auto_backtrace = 1;
2699 early_param("xmon", early_parse_xmon);
2701 void __init xmon_setup(void)
2703 #ifdef CONFIG_XMON_DEFAULT
2711 #ifdef CONFIG_SPU_BASE
2715 u64 saved_mfc_sr1_RW;
2716 u32 saved_spu_runcntl_RW;
2717 unsigned long dump_addr;
2721 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
2723 static struct spu_info spu_info[XMON_NUM_SPUS];
2725 void xmon_register_spus(struct list_head *list)
2729 list_for_each_entry(spu, list, full_list) {
2730 if (spu->number >= XMON_NUM_SPUS) {
2735 spu_info[spu->number].spu = spu;
2736 spu_info[spu->number].stopped_ok = 0;
2737 spu_info[spu->number].dump_addr = (unsigned long)
2738 spu_info[spu->number].spu->local_store;
2742 static void stop_spus(void)
2748 for (i = 0; i < XMON_NUM_SPUS; i++) {
2749 if (!spu_info[i].spu)
2752 if (setjmp(bus_error_jmp) == 0) {
2753 catch_memory_errors = 1;
2756 spu = spu_info[i].spu;
2758 spu_info[i].saved_spu_runcntl_RW =
2759 in_be32(&spu->problem->spu_runcntl_RW);
2761 tmp = spu_mfc_sr1_get(spu);
2762 spu_info[i].saved_mfc_sr1_RW = tmp;
2764 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2765 spu_mfc_sr1_set(spu, tmp);
2770 spu_info[i].stopped_ok = 1;
2772 printf("Stopped spu %.2d (was %s)\n", i,
2773 spu_info[i].saved_spu_runcntl_RW ?
2774 "running" : "stopped");
2776 catch_memory_errors = 0;
2777 printf("*** Error stopping spu %.2d\n", i);
2779 catch_memory_errors = 0;
2783 static void restart_spus(void)
2788 for (i = 0; i < XMON_NUM_SPUS; i++) {
2789 if (!spu_info[i].spu)
2792 if (!spu_info[i].stopped_ok) {
2793 printf("*** Error, spu %d was not successfully stopped"
2794 ", not restarting\n", i);
2798 if (setjmp(bus_error_jmp) == 0) {
2799 catch_memory_errors = 1;
2802 spu = spu_info[i].spu;
2803 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2804 out_be32(&spu->problem->spu_runcntl_RW,
2805 spu_info[i].saved_spu_runcntl_RW);
2810 printf("Restarted spu %.2d\n", i);
2812 catch_memory_errors = 0;
2813 printf("*** Error restarting spu %.2d\n", i);
2815 catch_memory_errors = 0;
2819 #define DUMP_WIDTH 23
2820 #define DUMP_VALUE(format, field, value) \
2822 if (setjmp(bus_error_jmp) == 0) { \
2823 catch_memory_errors = 1; \
2825 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2830 catch_memory_errors = 0; \
2831 printf(" %-*s = *** Error reading field.\n", \
2832 DUMP_WIDTH, #field); \
2834 catch_memory_errors = 0; \
2837 #define DUMP_FIELD(obj, format, field) \
2838 DUMP_VALUE(format, field, obj->field)
2840 static void dump_spu_fields(struct spu *spu)
2842 printf("Dumping spu fields at address %p:\n", spu);
2844 DUMP_FIELD(spu, "0x%x", number);
2845 DUMP_FIELD(spu, "%s", name);
2846 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2847 DUMP_FIELD(spu, "0x%p", local_store);
2848 DUMP_FIELD(spu, "0x%lx", ls_size);
2849 DUMP_FIELD(spu, "0x%x", node);
2850 DUMP_FIELD(spu, "0x%lx", flags);
2851 DUMP_FIELD(spu, "%d", class_0_pending);
2852 DUMP_FIELD(spu, "0x%lx", class_0_dar);
2853 DUMP_FIELD(spu, "0x%lx", class_1_dar);
2854 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
2855 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2856 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2857 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2858 DUMP_FIELD(spu, "0x%x", slb_replace);
2859 DUMP_FIELD(spu, "%d", pid);
2860 DUMP_FIELD(spu, "0x%p", mm);
2861 DUMP_FIELD(spu, "0x%p", ctx);
2862 DUMP_FIELD(spu, "0x%p", rq);
2863 DUMP_FIELD(spu, "0x%p", timestamp);
2864 DUMP_FIELD(spu, "0x%lx", problem_phys);
2865 DUMP_FIELD(spu, "0x%p", problem);
2866 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2867 in_be32(&spu->problem->spu_runcntl_RW));
2868 DUMP_VALUE("0x%x", problem->spu_status_R,
2869 in_be32(&spu->problem->spu_status_R));
2870 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2871 in_be32(&spu->problem->spu_npc_RW));
2872 DUMP_FIELD(spu, "0x%p", priv2);
2873 DUMP_FIELD(spu, "0x%p", pdata);
2877 spu_inst_dump(unsigned long adr, long count, int praddr)
2879 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2882 static void dump_spu_ls(unsigned long num, int subcmd)
2884 unsigned long offset, addr, ls_addr;
2886 if (setjmp(bus_error_jmp) == 0) {
2887 catch_memory_errors = 1;
2889 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2893 catch_memory_errors = 0;
2894 printf("*** Error: accessing spu info for spu %d\n", num);
2897 catch_memory_errors = 0;
2899 if (scanhex(&offset))
2900 addr = ls_addr + offset;
2902 addr = spu_info[num].dump_addr;
2904 if (addr >= ls_addr + LS_SIZE) {
2905 printf("*** Error: address outside of local store\n");
2911 addr += spu_inst_dump(addr, 16, 1);
2921 spu_info[num].dump_addr = addr;
2924 static int do_spu_cmd(void)
2926 static unsigned long num = 0;
2927 int cmd, subcmd = 0;
2939 if (isxdigit(subcmd) || subcmd == '\n')
2943 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2944 printf("*** Error: invalid spu number\n");
2950 dump_spu_fields(spu_info[num].spu);
2953 dump_spu_ls(num, subcmd);
2964 #else /* ! CONFIG_SPU_BASE */
2965 static int do_spu_cmd(void)