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/kmsg_dump.h>
21 #include <linux/cpumask.h>
22 #include <linux/export.h>
23 #include <linux/sysrq.h>
24 #include <linux/interrupt.h>
25 #include <linux/irq.h>
26 #include <linux/bug.h>
27 #include <linux/nmi.h>
28 #include <linux/ctype.h>
30 #include <asm/ptrace.h>
31 #include <asm/string.h>
33 #include <asm/machdep.h>
35 #include <asm/processor.h>
36 #include <asm/pgtable.h>
38 #include <asm/mmu_context.h>
39 #include <asm/cputable.h>
41 #include <asm/sstep.h>
42 #include <asm/irq_regs.h>
44 #include <asm/spu_priv1.h>
45 #include <asm/setjmp.h>
47 #include <asm/debug.h>
48 #include <asm/hw_breakpoint.h>
51 #include <asm/hvcall.h>
55 #if defined(CONFIG_PPC_SPLPAR)
56 #include <asm/plpar_wrappers.h>
58 static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
65 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
66 static unsigned long xmon_taken = 1;
67 static int xmon_owner;
71 #endif /* CONFIG_SMP */
73 static unsigned long in_xmon __read_mostly = 0;
75 static unsigned long adrs;
77 #define MAX_DUMP (128 * 1024)
78 static unsigned long ndump = 64;
79 static unsigned long nidump = 16;
80 static unsigned long ncsum = 4096;
82 static char tmpstr[128];
84 static long bus_error_jmp[JMP_BUF_LEN];
85 static int catch_memory_errors;
86 static long *xmon_fault_jmp[NR_CPUS];
88 /* Breakpoint stuff */
90 unsigned long address;
91 unsigned int instr[2];
97 /* Bits in bpt.enabled */
103 static struct bpt bpts[NBPTS];
104 static struct bpt dabr;
105 static struct bpt *iabr;
106 static unsigned bpinstr = 0x7fe00008; /* trap */
108 #define BP_NUM(bp) ((bp) - bpts + 1)
111 static int cmds(struct pt_regs *);
112 static int mread(unsigned long, void *, int);
113 static int mwrite(unsigned long, void *, int);
114 static int handle_fault(struct pt_regs *);
115 static void byterev(unsigned char *, int);
116 static void memex(void);
117 static int bsesc(void);
118 static void dump(void);
119 static void prdump(unsigned long, long);
120 static int ppc_inst_dump(unsigned long, long, int);
121 static void dump_log_buf(void);
122 static void backtrace(struct pt_regs *);
123 static void excprint(struct pt_regs *);
124 static void prregs(struct pt_regs *);
125 static void memops(int);
126 static void memlocate(void);
127 static void memzcan(void);
128 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
130 int scanhex(unsigned long *valp);
131 static void scannl(void);
132 static int hexdigit(int);
133 void getstring(char *, int);
134 static void flush_input(void);
135 static int inchar(void);
136 static void take_input(char *);
137 static unsigned long read_spr(int);
138 static void write_spr(int, unsigned long);
139 static void super_regs(void);
140 static void remove_bpts(void);
141 static void insert_bpts(void);
142 static void remove_cpu_bpts(void);
143 static void insert_cpu_bpts(void);
144 static struct bpt *at_breakpoint(unsigned long pc);
145 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
146 static int do_step(struct pt_regs *);
147 static void bpt_cmds(void);
148 static void cacheflush(void);
149 static int cpu_cmd(void);
150 static void csum(void);
151 static void bootcmds(void);
152 static void proccall(void);
153 void dump_segments(void);
154 static void symbol_lookup(void);
155 static void xmon_show_stack(unsigned long sp, unsigned long lr,
157 static void xmon_print_symbol(unsigned long address, const char *mid,
159 static const char *getvecname(unsigned long vec);
161 static int do_spu_cmd(void);
164 static void dump_tlb_44x(void);
166 #ifdef CONFIG_PPC_BOOK3E
167 static void dump_tlb_book3e(void);
170 static int xmon_no_auto_backtrace;
172 extern void xmon_enter(void);
173 extern void xmon_leave(void);
181 #ifdef __LITTLE_ENDIAN__
182 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
184 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
187 static char *help_string = "\
189 b show breakpoints\n\
190 bd set data breakpoint\n\
191 bi set instruction breakpoint\n\
192 bc clear breakpoint\n"
195 c print cpus stopped in xmon\n\
196 c# try to switch to cpu number h (in hex)\n"
201 di dump instructions\n\
202 df dump float values\n\
203 dd dump double values\n\
204 dl dump the kernel log buffer\n"
207 dp[#] dump paca for current cpu, or cpu #\n\
208 dpa dump paca for all possible cpus\n"
211 dr dump stream of raw bytes\n\
212 e print exception information\n\
214 la lookup symbol+offset of specified address\n\
215 ls lookup address of specified symbol\n\
216 m examine/change memory\n\
217 mm move a block of memory\n\
218 ms set a block of memory\n\
219 md compare two blocks of memory\n\
220 ml locate a block of memory\n\
221 mz zero a block of memory\n\
222 mi show information about memory allocation\n\
223 p call a procedure\n\
226 #ifdef CONFIG_SPU_BASE
227 " ss stop execution on all spus\n\
228 sr restore execution on stopped spus\n\
229 sf # dump spu fields for spu # (in hex)\n\
230 sd # dump spu local store for spu # (in hex)\n\
231 sdi # disassemble spu local store for spu # (in hex)\n"
233 " S print special registers\n\
235 x exit monitor and recover\n\
236 X exit monitor and dont recover\n"
237 #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
238 " u dump segment table or SLB\n"
239 #elif defined(CONFIG_PPC_STD_MMU_32)
240 " u dump segment registers\n"
241 #elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
245 " # n limit output to n lines per page (for dp, dpa, dl)\n"
250 static struct pt_regs *xmon_regs;
252 static inline void sync(void)
254 asm volatile("sync; isync");
257 static inline void store_inst(void *p)
259 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
262 static inline void cflush(void *p)
264 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
267 static inline void cinval(void *p)
269 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
273 * write_ciabr() - write the CIABR SPR
274 * @ciabr: The value to write.
276 * This function writes a value to the CIARB register either directly
277 * through mtspr instruction if the kernel is in HV privilege mode or
278 * call a hypervisor function to achieve the same in case the kernel
279 * is in supervisor privilege mode.
281 static void write_ciabr(unsigned long ciabr)
283 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
286 if (cpu_has_feature(CPU_FTR_HVMODE)) {
287 mtspr(SPRN_CIABR, ciabr);
290 plapr_set_ciabr(ciabr);
294 * set_ciabr() - set the CIABR
295 * @addr: The value to set.
297 * This function sets the correct privilege value into the the HW
298 * breakpoint address before writing it up in the CIABR register.
300 static void set_ciabr(unsigned long addr)
304 if (cpu_has_feature(CPU_FTR_HVMODE))
305 addr |= CIABR_PRIV_HYPER;
307 addr |= CIABR_PRIV_SUPER;
312 * Disable surveillance (the service processor watchdog function)
313 * while we are in xmon.
314 * XXX we should re-enable it when we leave. :)
316 #define SURVEILLANCE_TOKEN 9000
318 static inline void disable_surveillance(void)
320 #ifdef CONFIG_PPC_PSERIES
321 /* Since this can't be a module, args should end up below 4GB. */
322 static struct rtas_args args;
325 * At this point we have got all the cpus we can into
326 * xmon, so there is hopefully no other cpu calling RTAS
327 * at the moment, even though we don't take rtas.lock.
328 * If we did try to take rtas.lock there would be a
329 * real possibility of deadlock.
331 args.token = rtas_token("set-indicator");
332 if (args.token == RTAS_UNKNOWN_SERVICE)
334 args.token = cpu_to_be32(args.token);
335 args.nargs = cpu_to_be32(3);
336 args.nret = cpu_to_be32(1);
337 args.rets = &args.args[3];
338 args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
341 enter_rtas(__pa(&args));
342 #endif /* CONFIG_PPC_PSERIES */
346 static int xmon_speaker;
348 static void get_output_lock(void)
350 int me = smp_processor_id() + 0x100;
351 int last_speaker = 0, prev;
354 if (xmon_speaker == me)
358 last_speaker = cmpxchg(&xmon_speaker, 0, me);
359 if (last_speaker == 0)
363 * Wait a full second for the lock, we might be on a slow
364 * console, but check every 100us.
367 while (xmon_speaker == last_speaker) {
373 /* hostile takeover */
374 prev = cmpxchg(&xmon_speaker, last_speaker, me);
375 if (prev == last_speaker)
382 static void release_output_lock(void)
387 int cpus_are_in_xmon(void)
389 return !cpumask_empty(&cpus_in_xmon);
393 static inline int unrecoverable_excp(struct pt_regs *regs)
395 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
396 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
399 return ((regs->msr & MSR_RI) == 0);
403 static int xmon_core(struct pt_regs *regs, int fromipi)
407 long recurse_jmp[JMP_BUF_LEN];
408 unsigned long offset;
413 unsigned long timeout;
416 local_irq_save(flags);
419 bp = in_breakpoint_table(regs->nip, &offset);
421 regs->nip = bp->address + offset;
422 atomic_dec(&bp->ref_count);
428 cpu = smp_processor_id();
429 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
432 printf("cpu 0x%x: Exception %lx %s in xmon, "
433 "returning to main loop\n",
434 cpu, regs->trap, getvecname(TRAP(regs)));
435 release_output_lock();
436 longjmp(xmon_fault_jmp[cpu], 1);
439 if (setjmp(recurse_jmp) != 0) {
440 if (!in_xmon || !xmon_gate) {
442 printf("xmon: WARNING: bad recursive fault "
443 "on cpu 0x%x\n", cpu);
444 release_output_lock();
447 secondary = !(xmon_taken && cpu == xmon_owner);
451 xmon_fault_jmp[cpu] = recurse_jmp;
454 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
455 bp = at_breakpoint(regs->nip);
456 if (bp || unrecoverable_excp(regs))
463 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
465 xmon_print_symbol(regs->nip, " ", ")\n");
467 if (unrecoverable_excp(regs))
468 printf("WARNING: exception is not recoverable, "
470 release_output_lock();
473 cpumask_set_cpu(cpu, &cpus_in_xmon);
477 while (secondary && !xmon_gate) {
481 secondary = test_and_set_bit(0, &in_xmon);
486 if (!secondary && !xmon_gate) {
487 /* we are the first cpu to come in */
488 /* interrupt other cpu(s) */
489 int ncpus = num_online_cpus();
494 smp_send_debugger_break();
495 /* wait for other cpus to come in */
496 for (timeout = 100000000; timeout != 0; --timeout) {
497 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
503 disable_surveillance();
504 /* for breakpoint or single step, print the current instr. */
505 if (bp || TRAP(regs) == 0xd00)
506 ppc_inst_dump(regs->nip, 1, 0);
507 printf("enter ? for help\n");
516 if (cpu == xmon_owner) {
517 if (!test_and_set_bit(0, &xmon_taken)) {
522 while (cpu == xmon_owner)
536 /* have switched to some other cpu */
541 cpumask_clear_cpu(cpu, &cpus_in_xmon);
542 xmon_fault_jmp[cpu] = NULL;
544 /* UP is simple... */
546 printf("Exception %lx %s in xmon, returning to main loop\n",
547 regs->trap, getvecname(TRAP(regs)));
548 longjmp(xmon_fault_jmp[0], 1);
550 if (setjmp(recurse_jmp) == 0) {
551 xmon_fault_jmp[0] = recurse_jmp;
555 bp = at_breakpoint(regs->nip);
557 printf("Stopped at breakpoint %lx (", BP_NUM(bp));
558 xmon_print_symbol(regs->nip, " ", ")\n");
560 if (unrecoverable_excp(regs))
561 printf("WARNING: exception is not recoverable, "
564 disable_surveillance();
565 /* for breakpoint or single step, print the current instr. */
566 if (bp || TRAP(regs) == 0xd00)
567 ppc_inst_dump(regs->nip, 1, 0);
568 printf("enter ? for help\n");
578 if (regs->msr & MSR_DE) {
579 bp = at_breakpoint(regs->nip);
581 regs->nip = (unsigned long) &bp->instr[0];
582 atomic_inc(&bp->ref_count);
586 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
587 bp = at_breakpoint(regs->nip);
589 int stepped = emulate_step(regs, bp->instr[0]);
591 regs->nip = (unsigned long) &bp->instr[0];
592 atomic_inc(&bp->ref_count);
593 } else if (stepped < 0) {
594 printf("Couldn't single-step %s instruction\n",
595 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
602 touch_nmi_watchdog();
603 local_irq_restore(flags);
605 return cmd != 'X' && cmd != EOF;
608 int xmon(struct pt_regs *excp)
613 ppc_save_regs(®s);
617 return xmon_core(excp, 0);
621 irqreturn_t xmon_irq(int irq, void *d)
624 local_irq_save(flags);
625 printf("Keyboard interrupt\n");
626 xmon(get_irq_regs());
627 local_irq_restore(flags);
631 static int xmon_bpt(struct pt_regs *regs)
634 unsigned long offset;
636 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
639 /* Are we at the trap at bp->instr[1] for some bp? */
640 bp = in_breakpoint_table(regs->nip, &offset);
641 if (bp != NULL && offset == 4) {
642 regs->nip = bp->address + 4;
643 atomic_dec(&bp->ref_count);
647 /* Are we at a breakpoint? */
648 bp = at_breakpoint(regs->nip);
657 static int xmon_sstep(struct pt_regs *regs)
665 static int xmon_break_match(struct pt_regs *regs)
667 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
669 if (dabr.enabled == 0)
675 static int xmon_iabr_match(struct pt_regs *regs)
677 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
685 static int xmon_ipi(struct pt_regs *regs)
688 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
694 static int xmon_fault_handler(struct pt_regs *regs)
697 unsigned long offset;
699 if (in_xmon && catch_memory_errors)
700 handle_fault(regs); /* doesn't return */
702 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
703 bp = in_breakpoint_table(regs->nip, &offset);
705 regs->nip = bp->address + offset;
706 atomic_dec(&bp->ref_count);
713 static struct bpt *at_breakpoint(unsigned long pc)
719 for (i = 0; i < NBPTS; ++i, ++bp)
720 if (bp->enabled && pc == bp->address)
725 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
729 off = nip - (unsigned long) bpts;
730 if (off >= sizeof(bpts))
732 off %= sizeof(struct bpt);
733 if (off != offsetof(struct bpt, instr[0])
734 && off != offsetof(struct bpt, instr[1]))
736 *offp = off - offsetof(struct bpt, instr[0]);
737 return (struct bpt *) (nip - off);
740 static struct bpt *new_breakpoint(unsigned long a)
745 bp = at_breakpoint(a);
749 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
750 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
752 bp->instr[1] = bpinstr;
753 store_inst(&bp->instr[1]);
758 printf("Sorry, no free breakpoints. Please clear one first.\n");
762 static void insert_bpts(void)
768 for (i = 0; i < NBPTS; ++i, ++bp) {
769 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
771 if (mread(bp->address, &bp->instr[0], 4) != 4) {
772 printf("Couldn't read instruction at %lx, "
773 "disabling breakpoint there\n", bp->address);
777 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
778 printf("Breakpoint at %lx is on an mtmsrd or rfid "
779 "instruction, disabling it\n", bp->address);
783 store_inst(&bp->instr[0]);
784 if (bp->enabled & BP_CIABR)
786 if (mwrite(bp->address, &bpinstr, 4) != 4) {
787 printf("Couldn't write instruction at %lx, "
788 "disabling breakpoint there\n", bp->address);
789 bp->enabled &= ~BP_TRAP;
792 store_inst((void *)bp->address);
796 static void insert_cpu_bpts(void)
798 struct arch_hw_breakpoint brk;
801 brk.address = dabr.address;
802 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
804 __set_breakpoint(&brk);
808 set_ciabr(iabr->address);
811 static void remove_bpts(void)
818 for (i = 0; i < NBPTS; ++i, ++bp) {
819 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
821 if (mread(bp->address, &instr, 4) == 4
823 && mwrite(bp->address, &bp->instr, 4) != 4)
824 printf("Couldn't remove breakpoint at %lx\n",
827 store_inst((void *)bp->address);
831 static void remove_cpu_bpts(void)
833 hw_breakpoint_disable();
837 static void set_lpp_cmd(void)
841 if (!scanhex(&lpp)) {
842 printf("Invalid number.\n");
845 xmon_set_pagination_lpp(lpp);
847 /* Command interpreting routine */
848 static char *last_cmd;
851 cmds(struct pt_regs *excp)
858 if (!xmon_no_auto_backtrace) {
859 xmon_no_auto_backtrace = 1;
860 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
865 printf("%x:", smp_processor_id());
866 #endif /* CONFIG_SMP */
872 if (last_cmd == NULL)
874 take_input(last_cmd);
908 prregs(excp); /* print regs */
923 if (do_spu_cmd() == 0)
932 printf(" <no input ...>\n");
936 xmon_puts(help_string);
957 #ifdef CONFIG_PPC_STD_MMU
961 #elif defined(CONFIG_44x)
965 #elif defined(CONFIG_PPC_BOOK3E)
971 printf("Unrecognized command: ");
973 if (' ' < cmd && cmd <= '~')
976 printf("\\x%x", cmd);
978 } while (cmd != '\n');
979 printf(" (type ? for help)\n");
986 static int do_step(struct pt_regs *regs)
989 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
994 * Step a single instruction.
995 * Some instructions we emulate, others we execute with MSR_SE set.
997 static int do_step(struct pt_regs *regs)
1002 /* check we are in 64-bit kernel mode, translation enabled */
1003 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1004 if (mread(regs->nip, &instr, 4) == 4) {
1005 stepped = emulate_step(regs, instr);
1007 printf("Couldn't single-step %s instruction\n",
1008 (IS_RFID(instr)? "rfid": "mtmsrd"));
1012 regs->trap = 0xd00 | (regs->trap & 1);
1013 printf("stepped to ");
1014 xmon_print_symbol(regs->nip, " ", "\n");
1015 ppc_inst_dump(regs->nip, 1, 0);
1020 regs->msr |= MSR_SE;
1025 static void bootcmds(void)
1031 ppc_md.restart(NULL);
1032 else if (cmd == 'h')
1034 else if (cmd == 'p')
1039 static int cpu_cmd(void)
1042 unsigned long cpu, first_cpu, last_cpu;
1045 if (!scanhex(&cpu)) {
1046 /* print cpus waiting or in xmon */
1047 printf("cpus stopped:");
1048 last_cpu = first_cpu = NR_CPUS;
1049 for_each_possible_cpu(cpu) {
1050 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1051 if (cpu == last_cpu + 1) {
1054 if (last_cpu != first_cpu)
1055 printf("-0x%lx", last_cpu);
1056 last_cpu = first_cpu = cpu;
1057 printf(" 0x%lx", cpu);
1061 if (last_cpu != first_cpu)
1062 printf("-0x%lx", last_cpu);
1066 /* try to switch to cpu specified */
1067 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1068 printf("cpu 0x%x isn't in xmon\n", cpu);
1075 while (!xmon_taken) {
1076 if (--timeout == 0) {
1077 if (test_and_set_bit(0, &xmon_taken))
1079 /* take control back */
1081 xmon_owner = smp_processor_id();
1082 printf("cpu 0x%x didn't take control\n", cpu);
1090 #endif /* CONFIG_SMP */
1093 static unsigned short fcstab[256] = {
1094 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1095 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1096 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1097 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1098 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1099 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1100 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1101 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1102 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1103 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1104 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1105 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1106 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1107 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1108 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1109 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1110 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1111 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1112 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1113 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1114 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1115 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1116 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1117 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1118 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1119 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1120 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1121 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1122 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1123 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1124 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1125 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1128 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1137 if (!scanhex(&adrs))
1139 if (!scanhex(&ncsum))
1142 for (i = 0; i < ncsum; ++i) {
1143 if (mread(adrs+i, &v, 1) == 0) {
1144 printf("csum stopped at "REG"\n", adrs+i);
1149 printf("%x\n", fcs);
1153 * Check if this is a suitable place to put a breakpoint.
1155 static long check_bp_loc(unsigned long addr)
1160 if (!is_kernel_addr(addr)) {
1161 printf("Breakpoints may only be placed at kernel addresses\n");
1164 if (!mread(addr, &instr, sizeof(instr))) {
1165 printf("Can't read instruction at address %lx\n", addr);
1168 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1169 printf("Breakpoints may not be placed on mtmsrd or rfid "
1176 static char *breakpoint_help_string =
1177 "Breakpoint command usage:\n"
1178 "b show breakpoints\n"
1179 "b <addr> [cnt] set breakpoint at given instr addr\n"
1180 "bc clear all breakpoints\n"
1181 "bc <n/addr> clear breakpoint number n or at addr\n"
1182 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1183 "bd <addr> [cnt] set hardware data breakpoint\n"
1193 const char badaddr[] = "Only kernel addresses are permitted "
1194 "for breakpoints\n";
1199 case 'd': /* bd - hardware data breakpoint */
1204 else if (cmd == 'w')
1210 if (scanhex(&dabr.address)) {
1211 if (!is_kernel_addr(dabr.address)) {
1215 dabr.address &= ~HW_BRK_TYPE_DABR;
1216 dabr.enabled = mode | BP_DABR;
1220 case 'i': /* bi - hardware instr breakpoint */
1221 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1222 printf("Hardware instruction breakpoint "
1223 "not supported on this cpu\n");
1227 iabr->enabled &= ~BP_CIABR;
1232 if (!check_bp_loc(a))
1234 bp = new_breakpoint(a);
1236 bp->enabled |= BP_CIABR;
1244 /* clear all breakpoints */
1245 for (i = 0; i < NBPTS; ++i)
1246 bpts[i].enabled = 0;
1249 printf("All breakpoints cleared\n");
1253 if (a <= NBPTS && a >= 1) {
1254 /* assume a breakpoint number */
1255 bp = &bpts[a-1]; /* bp nums are 1 based */
1257 /* assume a breakpoint address */
1258 bp = at_breakpoint(a);
1260 printf("No breakpoint at %lx\n", a);
1265 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1266 xmon_print_symbol(bp->address, " ", ")\n");
1274 printf(breakpoint_help_string);
1279 /* print all breakpoints */
1280 printf(" type address\n");
1282 printf(" data "REG" [", dabr.address);
1283 if (dabr.enabled & 1)
1285 if (dabr.enabled & 2)
1289 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1292 printf("%2x %s ", BP_NUM(bp),
1293 (bp->enabled & BP_CIABR) ? "inst": "trap");
1294 xmon_print_symbol(bp->address, " ", "\n");
1299 if (!check_bp_loc(a))
1301 bp = new_breakpoint(a);
1303 bp->enabled |= BP_TRAP;
1308 /* Very cheap human name for vector lookup. */
1310 const char *getvecname(unsigned long vec)
1315 case 0x100: ret = "(System Reset)"; break;
1316 case 0x200: ret = "(Machine Check)"; break;
1317 case 0x300: ret = "(Data Access)"; break;
1318 case 0x380: ret = "(Data SLB Access)"; break;
1319 case 0x400: ret = "(Instruction Access)"; break;
1320 case 0x480: ret = "(Instruction SLB Access)"; break;
1321 case 0x500: ret = "(Hardware Interrupt)"; break;
1322 case 0x600: ret = "(Alignment)"; break;
1323 case 0x700: ret = "(Program Check)"; break;
1324 case 0x800: ret = "(FPU Unavailable)"; break;
1325 case 0x900: ret = "(Decrementer)"; break;
1326 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1327 case 0xa00: ret = "(Doorbell)"; break;
1328 case 0xc00: ret = "(System Call)"; break;
1329 case 0xd00: ret = "(Single Step)"; break;
1330 case 0xe40: ret = "(Emulation Assist)"; break;
1331 case 0xe60: ret = "(HMI)"; break;
1332 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1333 case 0xf00: ret = "(Performance Monitor)"; break;
1334 case 0xf20: ret = "(Altivec Unavailable)"; break;
1335 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1336 case 0x1500: ret = "(Denormalisation)"; break;
1337 case 0x1700: ret = "(Altivec Assist)"; break;
1343 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1344 unsigned long *endp)
1346 unsigned long size, offset;
1349 *startp = *endp = 0;
1352 if (setjmp(bus_error_jmp) == 0) {
1353 catch_memory_errors = 1;
1355 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1357 *startp = pc - offset;
1358 *endp = pc - offset + size;
1362 catch_memory_errors = 0;
1365 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1366 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1368 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1371 int max_to_print = 64;
1373 unsigned long newsp;
1374 unsigned long marker;
1375 struct pt_regs regs;
1377 while (max_to_print--) {
1378 if (sp < PAGE_OFFSET) {
1380 printf("SP (%lx) is in userspace\n", sp);
1384 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1385 || !mread(sp, &newsp, sizeof(unsigned long))) {
1386 printf("Couldn't read stack frame at %lx\n", sp);
1391 * For the first stack frame, try to work out if
1392 * LR and/or the saved LR value in the bottommost
1393 * stack frame are valid.
1395 if ((pc | lr) != 0) {
1396 unsigned long fnstart, fnend;
1397 unsigned long nextip;
1400 get_function_bounds(pc, &fnstart, &fnend);
1403 mread(newsp + LRSAVE_OFFSET, &nextip,
1404 sizeof(unsigned long));
1406 if (lr < PAGE_OFFSET
1407 || (fnstart <= lr && lr < fnend))
1409 } else if (lr == nextip) {
1411 } else if (lr >= PAGE_OFFSET
1412 && !(fnstart <= lr && lr < fnend)) {
1413 printf("[link register ] ");
1414 xmon_print_symbol(lr, " ", "\n");
1417 printf("["REG"] ", sp);
1418 xmon_print_symbol(ip, " ", " (unreliable)\n");
1423 printf("["REG"] ", sp);
1424 xmon_print_symbol(ip, " ", "\n");
1427 /* Look for "regshere" marker to see if this is
1428 an exception frame. */
1429 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1430 && marker == STACK_FRAME_REGS_MARKER) {
1431 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1433 printf("Couldn't read registers at %lx\n",
1434 sp + STACK_FRAME_OVERHEAD);
1437 printf("--- Exception: %lx %s at ", regs.trap,
1438 getvecname(TRAP(®s)));
1441 xmon_print_symbol(pc, " ", "\n");
1451 static void backtrace(struct pt_regs *excp)
1456 xmon_show_stack(sp, 0, 0);
1458 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1462 static void print_bug_trap(struct pt_regs *regs)
1465 const struct bug_entry *bug;
1468 if (regs->msr & MSR_PR)
1469 return; /* not in kernel */
1470 addr = regs->nip; /* address of trap instruction */
1471 if (addr < PAGE_OFFSET)
1473 bug = find_bug(regs->nip);
1476 if (is_warning_bug(bug))
1479 #ifdef CONFIG_DEBUG_BUGVERBOSE
1480 printf("kernel BUG at %s:%u!\n",
1481 bug->file, bug->line);
1483 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1485 #endif /* CONFIG_BUG */
1488 static void excprint(struct pt_regs *fp)
1493 printf("cpu 0x%x: ", smp_processor_id());
1494 #endif /* CONFIG_SMP */
1497 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1499 xmon_print_symbol(fp->nip, ": ", "\n");
1501 printf(" lr: ", fp->link);
1502 xmon_print_symbol(fp->link, ": ", "\n");
1504 printf(" sp: %lx\n", fp->gpr[1]);
1505 printf(" msr: %lx\n", fp->msr);
1507 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1508 printf(" dar: %lx\n", fp->dar);
1510 printf(" dsisr: %lx\n", fp->dsisr);
1513 printf(" current = 0x%lx\n", current);
1515 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1516 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1519 printf(" pid = %ld, comm = %s\n",
1520 current->pid, current->comm);
1527 static void prregs(struct pt_regs *fp)
1531 struct pt_regs regs;
1533 if (scanhex(&base)) {
1534 if (setjmp(bus_error_jmp) == 0) {
1535 catch_memory_errors = 1;
1537 regs = *(struct pt_regs *)base;
1541 catch_memory_errors = 0;
1542 printf("*** Error reading registers from "REG"\n",
1546 catch_memory_errors = 0;
1551 if (FULL_REGS(fp)) {
1552 for (n = 0; n < 16; ++n)
1553 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1554 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1556 for (n = 0; n < 7; ++n)
1557 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1558 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1561 for (n = 0; n < 32; ++n) {
1562 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1563 (n & 3) == 3? "\n": " ");
1564 if (n == 12 && !FULL_REGS(fp)) {
1571 xmon_print_symbol(fp->nip, " ", "\n");
1572 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1574 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1577 xmon_print_symbol(fp->link, " ", "\n");
1578 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1579 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1580 fp->ctr, fp->xer, fp->trap);
1582 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1583 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1586 static void cacheflush(void)
1589 unsigned long nflush;
1594 scanhex((void *)&adrs);
1599 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1600 if (setjmp(bus_error_jmp) == 0) {
1601 catch_memory_errors = 1;
1605 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1606 cflush((void *) adrs);
1608 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1609 cinval((void *) adrs);
1612 /* wait a little while to see if we get a machine check */
1615 catch_memory_errors = 0;
1618 static unsigned long
1621 unsigned int instrs[2];
1622 unsigned long (*code)(void);
1623 unsigned long ret = -1UL;
1625 unsigned long opd[3];
1627 opd[0] = (unsigned long)instrs;
1630 code = (unsigned long (*)(void)) opd;
1632 code = (unsigned long (*)(void)) instrs;
1635 /* mfspr r3,n; blr */
1636 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1637 instrs[1] = 0x4e800020;
1639 store_inst(instrs+1);
1641 if (setjmp(bus_error_jmp) == 0) {
1642 catch_memory_errors = 1;
1648 /* wait a little while to see if we get a machine check */
1657 write_spr(int n, unsigned long val)
1659 unsigned int instrs[2];
1660 unsigned long (*code)(unsigned long);
1662 unsigned long opd[3];
1664 opd[0] = (unsigned long)instrs;
1667 code = (unsigned long (*)(unsigned long)) opd;
1669 code = (unsigned long (*)(unsigned long)) instrs;
1672 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1673 instrs[1] = 0x4e800020;
1675 store_inst(instrs+1);
1677 if (setjmp(bus_error_jmp) == 0) {
1678 catch_memory_errors = 1;
1684 /* wait a little while to see if we get a machine check */
1690 static unsigned long regno;
1691 extern char exc_prolog;
1692 extern char dec_exc;
1694 static void super_regs(void)
1701 unsigned long sp, toc;
1702 asm("mr %0,1" : "=r" (sp) :);
1703 asm("mr %0,2" : "=r" (toc) :);
1705 printf("msr = "REG" sprg0= "REG"\n",
1706 mfmsr(), mfspr(SPRN_SPRG0));
1707 printf("pvr = "REG" sprg1= "REG"\n",
1708 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1709 printf("dec = "REG" sprg2= "REG"\n",
1710 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1711 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1712 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1720 val = read_spr(regno);
1722 write_spr(regno, val);
1725 printf("spr %lx = %lx\n", regno, read_spr(regno));
1732 * Stuff for reading and writing memory safely
1735 mread(unsigned long adrs, void *buf, int size)
1741 if (setjmp(bus_error_jmp) == 0) {
1742 catch_memory_errors = 1;
1748 *(u16 *)q = *(u16 *)p;
1751 *(u32 *)q = *(u32 *)p;
1754 *(u64 *)q = *(u64 *)p;
1757 for( ; n < size; ++n) {
1763 /* wait a little while to see if we get a machine check */
1767 catch_memory_errors = 0;
1772 mwrite(unsigned long adrs, void *buf, int size)
1778 if (setjmp(bus_error_jmp) == 0) {
1779 catch_memory_errors = 1;
1785 *(u16 *)p = *(u16 *)q;
1788 *(u32 *)p = *(u32 *)q;
1791 *(u64 *)p = *(u64 *)q;
1794 for ( ; n < size; ++n) {
1800 /* wait a little while to see if we get a machine check */
1804 printf("*** Error writing address "REG"\n", adrs + n);
1806 catch_memory_errors = 0;
1810 static int fault_type;
1811 static int fault_except;
1812 static char *fault_chars[] = { "--", "**", "##" };
1814 static int handle_fault(struct pt_regs *regs)
1816 fault_except = TRAP(regs);
1817 switch (TRAP(regs)) {
1829 longjmp(bus_error_jmp, 1);
1834 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1837 byterev(unsigned char *val, int size)
1843 SWAP(val[0], val[1], t);
1846 SWAP(val[0], val[3], t);
1847 SWAP(val[1], val[2], t);
1849 case 8: /* is there really any use for this? */
1850 SWAP(val[0], val[7], t);
1851 SWAP(val[1], val[6], t);
1852 SWAP(val[2], val[5], t);
1853 SWAP(val[3], val[4], t);
1861 static char *memex_help_string =
1862 "Memory examine command usage:\n"
1863 "m [addr] [flags] examine/change memory\n"
1864 " addr is optional. will start where left off.\n"
1865 " flags may include chars from this set:\n"
1866 " b modify by bytes (default)\n"
1867 " w modify by words (2 byte)\n"
1868 " l modify by longs (4 byte)\n"
1869 " d modify by doubleword (8 byte)\n"
1870 " r toggle reverse byte order mode\n"
1871 " n do not read memory (for i/o spaces)\n"
1872 " . ok to read (default)\n"
1873 "NOTE: flags are saved as defaults\n"
1876 static char *memex_subcmd_help_string =
1877 "Memory examine subcommands:\n"
1878 " hexval write this val to current location\n"
1879 " 'string' write chars from string to this location\n"
1880 " ' increment address\n"
1881 " ^ decrement address\n"
1882 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1883 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1884 " ` clear no-read flag\n"
1885 " ; stay at this addr\n"
1886 " v change to byte mode\n"
1887 " w change to word (2 byte) mode\n"
1888 " l change to long (4 byte) mode\n"
1889 " u change to doubleword (8 byte) mode\n"
1890 " m addr change current addr\n"
1891 " n toggle no-read flag\n"
1892 " r toggle byte reverse flag\n"
1893 " < count back up count bytes\n"
1894 " > count skip forward count bytes\n"
1895 " x exit this mode\n"
1901 int cmd, inc, i, nslash;
1903 unsigned char val[16];
1905 scanhex((void *)&adrs);
1908 printf(memex_help_string);
1914 while ((cmd = skipbl()) != '\n') {
1916 case 'b': size = 1; break;
1917 case 'w': size = 2; break;
1918 case 'l': size = 4; break;
1919 case 'd': size = 8; break;
1920 case 'r': brev = !brev; break;
1921 case 'n': mnoread = 1; break;
1922 case '.': mnoread = 0; break;
1931 n = mread(adrs, val, size);
1932 printf(REG"%c", adrs, brev? 'r': ' ');
1937 for (i = 0; i < n; ++i)
1938 printf("%.2x", val[i]);
1939 for (; i < size; ++i)
1940 printf("%s", fault_chars[fault_type]);
1947 for (i = 0; i < size; ++i)
1948 val[i] = n >> (i * 8);
1951 mwrite(adrs, val, size);
1964 else if( n == '\'' )
1966 for (i = 0; i < size; ++i)
1967 val[i] = n >> (i * 8);
1970 mwrite(adrs, val, size);
2006 adrs -= 1 << nslash;
2010 adrs += 1 << nslash;
2014 adrs += 1 << -nslash;
2018 adrs -= 1 << -nslash;
2021 scanhex((void *)&adrs);
2040 printf(memex_subcmd_help_string);
2055 case 'n': c = '\n'; break;
2056 case 'r': c = '\r'; break;
2057 case 'b': c = '\b'; break;
2058 case 't': c = '\t'; break;
2063 static void xmon_rawdump (unsigned long adrs, long ndump)
2066 unsigned char temp[16];
2068 for (n = ndump; n > 0;) {
2070 nr = mread(adrs, temp, r);
2072 for (m = 0; m < r; ++m) {
2074 printf("%.2x", temp[m]);
2076 printf("%s", fault_chars[fault_type]);
2086 static void dump_one_paca(int cpu)
2088 struct paca_struct *p;
2089 #ifdef CONFIG_PPC_STD_MMU_64
2093 if (setjmp(bus_error_jmp) != 0) {
2094 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2098 catch_memory_errors = 1;
2103 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2105 printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu) ? "yes" : "no");
2106 printf(" %-*s = %s\n", 20, "present", cpu_present(cpu) ? "yes" : "no");
2107 printf(" %-*s = %s\n", 20, "online", cpu_online(cpu) ? "yes" : "no");
2109 #define DUMP(paca, name, format) \
2110 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
2111 offsetof(struct paca_struct, name));
2113 DUMP(p, lock_token, "x");
2114 DUMP(p, paca_index, "x");
2115 DUMP(p, kernel_toc, "lx");
2116 DUMP(p, kernelbase, "lx");
2117 DUMP(p, kernel_msr, "lx");
2118 DUMP(p, emergency_sp, "p");
2119 #ifdef CONFIG_PPC_BOOK3S_64
2120 DUMP(p, mc_emergency_sp, "p");
2121 DUMP(p, in_mce, "x");
2122 DUMP(p, hmi_event_available, "x");
2124 DUMP(p, data_offset, "lx");
2125 DUMP(p, hw_cpu_id, "x");
2126 DUMP(p, cpu_start, "x");
2127 DUMP(p, kexec_state, "x");
2128 #ifdef CONFIG_PPC_STD_MMU_64
2129 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2132 if (!p->slb_shadow_ptr)
2135 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2136 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2139 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2143 DUMP(p, vmalloc_sllp, "x");
2144 DUMP(p, slb_cache_ptr, "x");
2145 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2146 printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]);
2148 DUMP(p, rfi_flush_fallback_area, "px");
2150 DUMP(p, dscr_default, "llx");
2151 #ifdef CONFIG_PPC_BOOK3E
2153 DUMP(p, kernel_pgd, "p");
2154 DUMP(p, tcd_ptr, "p");
2155 DUMP(p, mc_kstack, "p");
2156 DUMP(p, crit_kstack, "p");
2157 DUMP(p, dbg_kstack, "p");
2159 DUMP(p, __current, "p");
2160 DUMP(p, kstack, "lx");
2161 DUMP(p, stab_rr, "lx");
2162 DUMP(p, saved_r1, "lx");
2163 DUMP(p, trap_save, "x");
2164 DUMP(p, soft_enabled, "x");
2165 DUMP(p, irq_happened, "x");
2166 DUMP(p, io_sync, "x");
2167 DUMP(p, irq_work_pending, "x");
2168 DUMP(p, nap_state_lost, "x");
2169 DUMP(p, sprg_vdso, "llx");
2171 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2172 DUMP(p, tm_scratch, "llx");
2175 #ifdef CONFIG_PPC_POWERNV
2176 DUMP(p, core_idle_state_ptr, "p");
2177 DUMP(p, thread_idle_state, "x");
2178 DUMP(p, thread_mask, "x");
2179 DUMP(p, subcore_sibling_mask, "x");
2182 DUMP(p, user_time, "llx");
2183 DUMP(p, system_time, "llx");
2184 DUMP(p, user_time_scaled, "llx");
2185 DUMP(p, starttime, "llx");
2186 DUMP(p, starttime_user, "llx");
2187 DUMP(p, startspurr, "llx");
2188 DUMP(p, utime_sspurr, "llx");
2189 DUMP(p, stolen_time, "llx");
2192 catch_memory_errors = 0;
2196 static void dump_all_pacas(void)
2200 if (num_possible_cpus() == 0) {
2201 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2205 for_each_possible_cpu(cpu)
2209 static void dump_pacas(void)
2220 termch = c; /* Put c back, it wasn't 'a' */
2225 dump_one_paca(xmon_owner);
2238 xmon_start_pagination();
2240 xmon_end_pagination();
2245 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2247 scanhex((void *)&adrs);
2254 else if (nidump > MAX_DUMP)
2256 adrs += ppc_inst_dump(adrs, nidump, 1);
2258 } else if (c == 'l') {
2260 } else if (c == 'r') {
2264 xmon_rawdump(adrs, ndump);
2271 else if (ndump > MAX_DUMP)
2273 prdump(adrs, ndump);
2280 prdump(unsigned long adrs, long ndump)
2282 long n, m, c, r, nr;
2283 unsigned char temp[16];
2285 for (n = ndump; n > 0;) {
2289 nr = mread(adrs, temp, r);
2291 for (m = 0; m < r; ++m) {
2292 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2295 printf("%.2x", temp[m]);
2297 printf("%s", fault_chars[fault_type]);
2299 for (; m < 16; ++m) {
2300 if ((m & (sizeof(long) - 1)) == 0)
2305 for (m = 0; m < r; ++m) {
2308 putchar(' ' <= c && c <= '~'? c: '.');
2321 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2324 generic_inst_dump(unsigned long adr, long count, int praddr,
2325 instruction_dump_func dump_func)
2328 unsigned long first_adr;
2329 unsigned long inst, last_inst = 0;
2330 unsigned char val[4];
2333 for (first_adr = adr; count > 0; --count, adr += 4) {
2334 nr = mread(adr, val, 4);
2337 const char *x = fault_chars[fault_type];
2338 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2342 inst = GETWORD(val);
2343 if (adr > first_adr && inst == last_inst) {
2353 printf(REG" %.8x", adr, inst);
2355 dump_func(inst, adr);
2358 return adr - first_adr;
2362 ppc_inst_dump(unsigned long adr, long count, int praddr)
2364 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2368 print_address(unsigned long addr)
2370 xmon_print_symbol(addr, "\t# ", "");
2376 struct kmsg_dumper dumper = { .active = 1 };
2377 unsigned char buf[128];
2380 if (setjmp(bus_error_jmp) != 0) {
2381 printf("Error dumping printk buffer!\n");
2385 catch_memory_errors = 1;
2388 kmsg_dump_rewind_nolock(&dumper);
2389 xmon_start_pagination();
2390 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2394 xmon_end_pagination();
2397 /* wait a little while to see if we get a machine check */
2399 catch_memory_errors = 0;
2403 * Memory operations - move, set, print differences
2405 static unsigned long mdest; /* destination address */
2406 static unsigned long msrc; /* source address */
2407 static unsigned long mval; /* byte value to set memory to */
2408 static unsigned long mcount; /* # bytes to affect */
2409 static unsigned long mdiffs; /* max # differences to print */
2414 scanhex((void *)&mdest);
2415 if( termch != '\n' )
2417 scanhex((void *)(cmd == 's'? &mval: &msrc));
2418 if( termch != '\n' )
2420 scanhex((void *)&mcount);
2423 memmove((void *)mdest, (void *)msrc, mcount);
2426 memset((void *)mdest, mval, mcount);
2429 if( termch != '\n' )
2431 scanhex((void *)&mdiffs);
2432 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2438 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2443 for( n = nb; n > 0; --n )
2444 if( *p1++ != *p2++ )
2445 if( ++prt <= maxpr )
2446 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2447 p1[-1], p2 - 1, p2[-1]);
2449 printf("Total of %d differences\n", prt);
2452 static unsigned mend;
2453 static unsigned mask;
2459 unsigned char val[4];
2462 scanhex((void *)&mdest);
2463 if (termch != '\n') {
2465 scanhex((void *)&mend);
2466 if (termch != '\n') {
2468 scanhex((void *)&mval);
2470 if (termch != '\n') termch = 0;
2471 scanhex((void *)&mask);
2475 for (a = mdest; a < mend; a += 4) {
2476 if (mread(a, val, 4) == 4
2477 && ((GETWORD(val) ^ mval) & mask) == 0) {
2478 printf("%.16x: %.16x\n", a, GETWORD(val));
2485 static unsigned long mskip = 0x1000;
2486 static unsigned long mlim = 0xffffffff;
2496 if (termch != '\n') termch = 0;
2498 if (termch != '\n') termch = 0;
2501 for (a = mdest; a < mlim; a += mskip) {
2502 ok = mread(a, &v, 1);
2504 printf("%.8x .. ", a);
2505 } else if (!ok && ook)
2506 printf("%.8x\n", a - mskip);
2512 printf("%.8x\n", a - mskip);
2515 static void proccall(void)
2517 unsigned long args[8];
2520 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2521 unsigned long, unsigned long, unsigned long,
2522 unsigned long, unsigned long, unsigned long);
2525 if (!scanhex(&adrs))
2529 for (i = 0; i < 8; ++i)
2531 for (i = 0; i < 8; ++i) {
2532 if (!scanhex(&args[i]) || termch == '\n')
2536 func = (callfunc_t) adrs;
2538 if (setjmp(bus_error_jmp) == 0) {
2539 catch_memory_errors = 1;
2541 ret = func(args[0], args[1], args[2], args[3],
2542 args[4], args[5], args[6], args[7]);
2544 printf("return value is 0x%lx\n", ret);
2546 printf("*** %x exception occurred\n", fault_except);
2548 catch_memory_errors = 0;
2551 /* Input scanning routines */
2562 while( c == ' ' || c == '\t' )
2568 static char *regnames[N_PTREGS] = {
2569 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2570 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2571 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2572 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2573 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2579 "trap", "dar", "dsisr", "res"
2583 scanhex(unsigned long *vp)
2590 /* parse register name */
2594 for (i = 0; i < sizeof(regname) - 1; ++i) {
2603 for (i = 0; i < N_PTREGS; ++i) {
2604 if (strcmp(regnames[i], regname) == 0) {
2605 if (xmon_regs == NULL) {
2606 printf("regs not available\n");
2609 *vp = ((unsigned long *)xmon_regs)[i];
2613 printf("invalid register name '%%%s'\n", regname);
2617 /* skip leading "0x" if any */
2631 } else if (c == '$') {
2633 for (i=0; i<63; i++) {
2635 if (isspace(c) || c == '\0') {
2643 if (setjmp(bus_error_jmp) == 0) {
2644 catch_memory_errors = 1;
2646 *vp = kallsyms_lookup_name(tmpstr);
2649 catch_memory_errors = 0;
2651 printf("unknown symbol '%s'\n", tmpstr);
2684 static int hexdigit(int c)
2686 if( '0' <= c && c <= '9' )
2688 if( 'A' <= c && c <= 'F' )
2689 return c - ('A' - 10);
2690 if( 'a' <= c && c <= 'f' )
2691 return c - ('a' - 10);
2696 getstring(char *s, int size)
2707 } while( c != ' ' && c != '\t' && c != '\n' );
2712 static char line[256];
2713 static char *lineptr;
2724 if (lineptr == NULL || *lineptr == 0) {
2725 if (xmon_gets(line, sizeof(line)) == NULL) {
2735 take_input(char *str)
2744 int type = inchar();
2746 static char tmp[64];
2751 xmon_print_symbol(addr, ": ", "\n");
2756 if (setjmp(bus_error_jmp) == 0) {
2757 catch_memory_errors = 1;
2759 addr = kallsyms_lookup_name(tmp);
2761 printf("%s: %lx\n", tmp, addr);
2763 printf("Symbol '%s' not found.\n", tmp);
2766 catch_memory_errors = 0;
2773 /* Print an address in numeric and symbolic form (if possible) */
2774 static void xmon_print_symbol(unsigned long address, const char *mid,
2778 const char *name = NULL;
2779 unsigned long offset, size;
2781 printf(REG, address);
2782 if (setjmp(bus_error_jmp) == 0) {
2783 catch_memory_errors = 1;
2785 name = kallsyms_lookup(address, &size, &offset, &modname,
2788 /* wait a little while to see if we get a machine check */
2792 catch_memory_errors = 0;
2795 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2797 printf(" [%s]", modname);
2799 printf("%s", after);
2802 #ifdef CONFIG_PPC_BOOK3S_64
2803 void dump_segments(void)
2806 unsigned long esid,vsid;
2809 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2811 for (i = 0; i < mmu_slb_size; i++) {
2812 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2813 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2815 printf("%02d %016lx %016lx", i, esid, vsid);
2816 if (esid & SLB_ESID_V) {
2817 llp = vsid & SLB_VSID_LLP;
2818 if (vsid & SLB_VSID_B_1T) {
2819 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2821 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2824 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2826 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2836 #ifdef CONFIG_PPC_STD_MMU_32
2837 void dump_segments(void)
2842 for (i = 0; i < 16; ++i)
2843 printf(" %x", mfsrin(i << 28));
2849 static void dump_tlb_44x(void)
2853 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2854 unsigned long w0,w1,w2;
2855 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2856 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2857 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2858 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2859 if (w0 & PPC44x_TLB_VALID) {
2860 printf("V %08x -> %01x%08x %c%c%c%c%c",
2861 w0 & PPC44x_TLB_EPN_MASK,
2862 w1 & PPC44x_TLB_ERPN_MASK,
2863 w1 & PPC44x_TLB_RPN_MASK,
2864 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2865 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2866 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2867 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2868 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2873 #endif /* CONFIG_44x */
2875 #ifdef CONFIG_PPC_BOOK3E
2876 static void dump_tlb_book3e(void)
2878 u32 mmucfg, pidmask, lpidmask;
2880 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2882 static const char *pgsz_names[] = {
2917 /* Gather some infos about the MMU */
2918 mmucfg = mfspr(SPRN_MMUCFG);
2919 mmu_version = (mmucfg & 3) + 1;
2920 ntlbs = ((mmucfg >> 2) & 3) + 1;
2921 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2922 lpidsz = (mmucfg >> 24) & 0xf;
2923 rasz = (mmucfg >> 16) & 0x7f;
2924 if ((mmu_version > 1) && (mmucfg & 0x10000))
2926 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2927 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2928 pidmask = (1ul << pidsz) - 1;
2929 lpidmask = (1ul << lpidsz) - 1;
2930 ramask = (1ull << rasz) - 1;
2932 for (tlb = 0; tlb < ntlbs; tlb++) {
2934 int nent, assoc, new_cc = 1;
2935 printf("TLB %d:\n------\n", tlb);
2938 tlbcfg = mfspr(SPRN_TLB0CFG);
2941 tlbcfg = mfspr(SPRN_TLB1CFG);
2944 tlbcfg = mfspr(SPRN_TLB2CFG);
2947 tlbcfg = mfspr(SPRN_TLB3CFG);
2950 printf("Unsupported TLB number !\n");
2953 nent = tlbcfg & 0xfff;
2954 assoc = (tlbcfg >> 24) & 0xff;
2955 for (i = 0; i < nent; i++) {
2956 u32 mas0 = MAS0_TLBSEL(tlb);
2957 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2960 int esel = i, cc = i;
2968 mas0 |= MAS0_ESEL(esel);
2969 mtspr(SPRN_MAS0, mas0);
2970 mtspr(SPRN_MAS1, mas1);
2971 mtspr(SPRN_MAS2, mas2);
2972 asm volatile("tlbre 0,0,0" : : : "memory");
2973 mas1 = mfspr(SPRN_MAS1);
2974 mas2 = mfspr(SPRN_MAS2);
2975 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2976 if (assoc && (i % assoc) == 0)
2978 if (!(mas1 & MAS1_VALID))
2981 printf("%04x- ", i);
2983 printf("%04x-%c", cc, 'A' + esel);
2985 printf(" |%c", 'A' + esel);
2987 printf(" %016llx %04x %s %c%c AS%c",
2989 (mas1 >> 16) & 0x3fff,
2990 pgsz_names[(mas1 >> 7) & 0x1f],
2991 mas1 & MAS1_IND ? 'I' : ' ',
2992 mas1 & MAS1_IPROT ? 'P' : ' ',
2993 mas1 & MAS1_TS ? '1' : '0');
2994 printf(" %c%c%c%c%c%c%c",
2995 mas2 & MAS2_X0 ? 'a' : ' ',
2996 mas2 & MAS2_X1 ? 'v' : ' ',
2997 mas2 & MAS2_W ? 'w' : ' ',
2998 mas2 & MAS2_I ? 'i' : ' ',
2999 mas2 & MAS2_M ? 'm' : ' ',
3000 mas2 & MAS2_G ? 'g' : ' ',
3001 mas2 & MAS2_E ? 'e' : ' ');
3002 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3003 if (mas1 & MAS1_IND)
3005 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3007 printf(" U%c%c%c S%c%c%c\n",
3008 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3009 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3010 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3011 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3012 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3013 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3017 #endif /* CONFIG_PPC_BOOK3E */
3019 static void xmon_init(int enable)
3023 __debugger_ipi = xmon_ipi;
3024 __debugger_bpt = xmon_bpt;
3025 __debugger_sstep = xmon_sstep;
3026 __debugger_iabr_match = xmon_iabr_match;
3027 __debugger_break_match = xmon_break_match;
3028 __debugger_fault_handler = xmon_fault_handler;
3031 __debugger_ipi = NULL;
3032 __debugger_bpt = NULL;
3033 __debugger_sstep = NULL;
3034 __debugger_iabr_match = NULL;
3035 __debugger_break_match = NULL;
3036 __debugger_fault_handler = NULL;
3040 #ifdef CONFIG_MAGIC_SYSRQ
3041 static void sysrq_handle_xmon(int key)
3043 /* ensure xmon is enabled */
3045 debugger(get_irq_regs());
3048 static struct sysrq_key_op sysrq_xmon_op = {
3049 .handler = sysrq_handle_xmon,
3050 .help_msg = "xmon(x)",
3051 .action_msg = "Entering xmon",
3054 static int __init setup_xmon_sysrq(void)
3056 register_sysrq_key('x', &sysrq_xmon_op);
3059 __initcall(setup_xmon_sysrq);
3060 #endif /* CONFIG_MAGIC_SYSRQ */
3062 static int __initdata xmon_early, xmon_off;
3064 static int __init early_parse_xmon(char *p)
3066 if (!p || strncmp(p, "early", 5) == 0) {
3067 /* just "xmon" is equivalent to "xmon=early" */
3070 } else if (strncmp(p, "on", 2) == 0)
3072 else if (strncmp(p, "off", 3) == 0)
3074 else if (strncmp(p, "nobt", 4) == 0)
3075 xmon_no_auto_backtrace = 1;
3081 early_param("xmon", early_parse_xmon);
3083 void __init xmon_setup(void)
3085 #ifdef CONFIG_XMON_DEFAULT
3093 #ifdef CONFIG_SPU_BASE
3097 u64 saved_mfc_sr1_RW;
3098 u32 saved_spu_runcntl_RW;
3099 unsigned long dump_addr;
3103 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3105 static struct spu_info spu_info[XMON_NUM_SPUS];
3107 void xmon_register_spus(struct list_head *list)
3111 list_for_each_entry(spu, list, full_list) {
3112 if (spu->number >= XMON_NUM_SPUS) {
3117 spu_info[spu->number].spu = spu;
3118 spu_info[spu->number].stopped_ok = 0;
3119 spu_info[spu->number].dump_addr = (unsigned long)
3120 spu_info[spu->number].spu->local_store;
3124 static void stop_spus(void)
3130 for (i = 0; i < XMON_NUM_SPUS; i++) {
3131 if (!spu_info[i].spu)
3134 if (setjmp(bus_error_jmp) == 0) {
3135 catch_memory_errors = 1;
3138 spu = spu_info[i].spu;
3140 spu_info[i].saved_spu_runcntl_RW =
3141 in_be32(&spu->problem->spu_runcntl_RW);
3143 tmp = spu_mfc_sr1_get(spu);
3144 spu_info[i].saved_mfc_sr1_RW = tmp;
3146 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3147 spu_mfc_sr1_set(spu, tmp);
3152 spu_info[i].stopped_ok = 1;
3154 printf("Stopped spu %.2d (was %s)\n", i,
3155 spu_info[i].saved_spu_runcntl_RW ?
3156 "running" : "stopped");
3158 catch_memory_errors = 0;
3159 printf("*** Error stopping spu %.2d\n", i);
3161 catch_memory_errors = 0;
3165 static void restart_spus(void)
3170 for (i = 0; i < XMON_NUM_SPUS; i++) {
3171 if (!spu_info[i].spu)
3174 if (!spu_info[i].stopped_ok) {
3175 printf("*** Error, spu %d was not successfully stopped"
3176 ", not restarting\n", i);
3180 if (setjmp(bus_error_jmp) == 0) {
3181 catch_memory_errors = 1;
3184 spu = spu_info[i].spu;
3185 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3186 out_be32(&spu->problem->spu_runcntl_RW,
3187 spu_info[i].saved_spu_runcntl_RW);
3192 printf("Restarted spu %.2d\n", i);
3194 catch_memory_errors = 0;
3195 printf("*** Error restarting spu %.2d\n", i);
3197 catch_memory_errors = 0;
3201 #define DUMP_WIDTH 23
3202 #define DUMP_VALUE(format, field, value) \
3204 if (setjmp(bus_error_jmp) == 0) { \
3205 catch_memory_errors = 1; \
3207 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3212 catch_memory_errors = 0; \
3213 printf(" %-*s = *** Error reading field.\n", \
3214 DUMP_WIDTH, #field); \
3216 catch_memory_errors = 0; \
3219 #define DUMP_FIELD(obj, format, field) \
3220 DUMP_VALUE(format, field, obj->field)
3222 static void dump_spu_fields(struct spu *spu)
3224 printf("Dumping spu fields at address %p:\n", spu);
3226 DUMP_FIELD(spu, "0x%x", number);
3227 DUMP_FIELD(spu, "%s", name);
3228 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3229 DUMP_FIELD(spu, "0x%p", local_store);
3230 DUMP_FIELD(spu, "0x%lx", ls_size);
3231 DUMP_FIELD(spu, "0x%x", node);
3232 DUMP_FIELD(spu, "0x%lx", flags);
3233 DUMP_FIELD(spu, "%d", class_0_pending);
3234 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3235 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3236 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3237 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3238 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3239 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3240 DUMP_FIELD(spu, "0x%x", slb_replace);
3241 DUMP_FIELD(spu, "%d", pid);
3242 DUMP_FIELD(spu, "0x%p", mm);
3243 DUMP_FIELD(spu, "0x%p", ctx);
3244 DUMP_FIELD(spu, "0x%p", rq);
3245 DUMP_FIELD(spu, "0x%p", timestamp);
3246 DUMP_FIELD(spu, "0x%lx", problem_phys);
3247 DUMP_FIELD(spu, "0x%p", problem);
3248 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3249 in_be32(&spu->problem->spu_runcntl_RW));
3250 DUMP_VALUE("0x%x", problem->spu_status_R,
3251 in_be32(&spu->problem->spu_status_R));
3252 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3253 in_be32(&spu->problem->spu_npc_RW));
3254 DUMP_FIELD(spu, "0x%p", priv2);
3255 DUMP_FIELD(spu, "0x%p", pdata);
3259 spu_inst_dump(unsigned long adr, long count, int praddr)
3261 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3264 static void dump_spu_ls(unsigned long num, int subcmd)
3266 unsigned long offset, addr, ls_addr;
3268 if (setjmp(bus_error_jmp) == 0) {
3269 catch_memory_errors = 1;
3271 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3275 catch_memory_errors = 0;
3276 printf("*** Error: accessing spu info for spu %d\n", num);
3279 catch_memory_errors = 0;
3281 if (scanhex(&offset))
3282 addr = ls_addr + offset;
3284 addr = spu_info[num].dump_addr;
3286 if (addr >= ls_addr + LS_SIZE) {
3287 printf("*** Error: address outside of local store\n");
3293 addr += spu_inst_dump(addr, 16, 1);
3303 spu_info[num].dump_addr = addr;
3306 static int do_spu_cmd(void)
3308 static unsigned long num = 0;
3309 int cmd, subcmd = 0;
3321 if (isxdigit(subcmd) || subcmd == '\n')
3325 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3326 printf("*** Error: invalid spu number\n");
3332 dump_spu_fields(spu_info[num].spu);
3335 dump_spu_ls(num, subcmd);
3346 #else /* ! CONFIG_SPU_BASE */
3347 static int do_spu_cmd(void)