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;
326 * At this point we have got all the cpus we can into
327 * xmon, so there is hopefully no other cpu calling RTAS
328 * at the moment, even though we don't take rtas.lock.
329 * If we did try to take rtas.lock there would be a
330 * real possibility of deadlock.
332 token = rtas_token("set-indicator");
333 if (token == RTAS_UNKNOWN_SERVICE)
336 rtas_call_unlocked(&args, token, 3, 1, NULL, SURVEILLANCE_TOKEN, 0, 0);
338 #endif /* CONFIG_PPC_PSERIES */
342 static int xmon_speaker;
344 static void get_output_lock(void)
346 int me = smp_processor_id() + 0x100;
347 int last_speaker = 0, prev;
350 if (xmon_speaker == me)
354 last_speaker = cmpxchg(&xmon_speaker, 0, me);
355 if (last_speaker == 0)
359 * Wait a full second for the lock, we might be on a slow
360 * console, but check every 100us.
363 while (xmon_speaker == last_speaker) {
369 /* hostile takeover */
370 prev = cmpxchg(&xmon_speaker, last_speaker, me);
371 if (prev == last_speaker)
378 static void release_output_lock(void)
383 int cpus_are_in_xmon(void)
385 return !cpumask_empty(&cpus_in_xmon);
389 static inline int unrecoverable_excp(struct pt_regs *regs)
391 #if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
392 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
395 return ((regs->msr & MSR_RI) == 0);
399 static int xmon_core(struct pt_regs *regs, int fromipi)
403 long recurse_jmp[JMP_BUF_LEN];
404 unsigned long offset;
409 unsigned long timeout;
412 local_irq_save(flags);
415 bp = in_breakpoint_table(regs->nip, &offset);
417 regs->nip = bp->address + offset;
418 atomic_dec(&bp->ref_count);
424 cpu = smp_processor_id();
425 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
428 printf("cpu 0x%x: Exception %lx %s in xmon, "
429 "returning to main loop\n",
430 cpu, regs->trap, getvecname(TRAP(regs)));
431 release_output_lock();
432 longjmp(xmon_fault_jmp[cpu], 1);
435 if (setjmp(recurse_jmp) != 0) {
436 if (!in_xmon || !xmon_gate) {
438 printf("xmon: WARNING: bad recursive fault "
439 "on cpu 0x%x\n", cpu);
440 release_output_lock();
443 secondary = !(xmon_taken && cpu == xmon_owner);
447 xmon_fault_jmp[cpu] = recurse_jmp;
450 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
451 bp = at_breakpoint(regs->nip);
452 if (bp || unrecoverable_excp(regs))
459 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
461 xmon_print_symbol(regs->nip, " ", ")\n");
463 if (unrecoverable_excp(regs))
464 printf("WARNING: exception is not recoverable, "
466 release_output_lock();
469 cpumask_set_cpu(cpu, &cpus_in_xmon);
473 while (secondary && !xmon_gate) {
477 secondary = test_and_set_bit(0, &in_xmon);
482 if (!secondary && !xmon_gate) {
483 /* we are the first cpu to come in */
484 /* interrupt other cpu(s) */
485 int ncpus = num_online_cpus();
490 smp_send_debugger_break();
491 /* wait for other cpus to come in */
492 for (timeout = 100000000; timeout != 0; --timeout) {
493 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
499 disable_surveillance();
500 /* for breakpoint or single step, print the current instr. */
501 if (bp || TRAP(regs) == 0xd00)
502 ppc_inst_dump(regs->nip, 1, 0);
503 printf("enter ? for help\n");
512 if (cpu == xmon_owner) {
513 if (!test_and_set_bit(0, &xmon_taken)) {
518 while (cpu == xmon_owner)
532 /* have switched to some other cpu */
537 cpumask_clear_cpu(cpu, &cpus_in_xmon);
538 xmon_fault_jmp[cpu] = NULL;
540 /* UP is simple... */
542 printf("Exception %lx %s in xmon, returning to main loop\n",
543 regs->trap, getvecname(TRAP(regs)));
544 longjmp(xmon_fault_jmp[0], 1);
546 if (setjmp(recurse_jmp) == 0) {
547 xmon_fault_jmp[0] = recurse_jmp;
551 bp = at_breakpoint(regs->nip);
553 printf("Stopped at breakpoint %lx (", BP_NUM(bp));
554 xmon_print_symbol(regs->nip, " ", ")\n");
556 if (unrecoverable_excp(regs))
557 printf("WARNING: exception is not recoverable, "
560 disable_surveillance();
561 /* for breakpoint or single step, print the current instr. */
562 if (bp || TRAP(regs) == 0xd00)
563 ppc_inst_dump(regs->nip, 1, 0);
564 printf("enter ? for help\n");
574 if (regs->msr & MSR_DE) {
575 bp = at_breakpoint(regs->nip);
577 regs->nip = (unsigned long) &bp->instr[0];
578 atomic_inc(&bp->ref_count);
582 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
583 bp = at_breakpoint(regs->nip);
585 int stepped = emulate_step(regs, bp->instr[0]);
587 regs->nip = (unsigned long) &bp->instr[0];
588 atomic_inc(&bp->ref_count);
589 } else if (stepped < 0) {
590 printf("Couldn't single-step %s instruction\n",
591 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
598 touch_nmi_watchdog();
599 local_irq_restore(flags);
601 return cmd != 'X' && cmd != EOF;
604 int xmon(struct pt_regs *excp)
609 ppc_save_regs(®s);
613 return xmon_core(excp, 0);
617 irqreturn_t xmon_irq(int irq, void *d)
620 local_irq_save(flags);
621 printf("Keyboard interrupt\n");
622 xmon(get_irq_regs());
623 local_irq_restore(flags);
627 static int xmon_bpt(struct pt_regs *regs)
630 unsigned long offset;
632 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
635 /* Are we at the trap at bp->instr[1] for some bp? */
636 bp = in_breakpoint_table(regs->nip, &offset);
637 if (bp != NULL && offset == 4) {
638 regs->nip = bp->address + 4;
639 atomic_dec(&bp->ref_count);
643 /* Are we at a breakpoint? */
644 bp = at_breakpoint(regs->nip);
653 static int xmon_sstep(struct pt_regs *regs)
661 static int xmon_break_match(struct pt_regs *regs)
663 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
665 if (dabr.enabled == 0)
671 static int xmon_iabr_match(struct pt_regs *regs)
673 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
681 static int xmon_ipi(struct pt_regs *regs)
684 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
690 static int xmon_fault_handler(struct pt_regs *regs)
693 unsigned long offset;
695 if (in_xmon && catch_memory_errors)
696 handle_fault(regs); /* doesn't return */
698 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
699 bp = in_breakpoint_table(regs->nip, &offset);
701 regs->nip = bp->address + offset;
702 atomic_dec(&bp->ref_count);
709 static struct bpt *at_breakpoint(unsigned long pc)
715 for (i = 0; i < NBPTS; ++i, ++bp)
716 if (bp->enabled && pc == bp->address)
721 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
725 off = nip - (unsigned long) bpts;
726 if (off >= sizeof(bpts))
728 off %= sizeof(struct bpt);
729 if (off != offsetof(struct bpt, instr[0])
730 && off != offsetof(struct bpt, instr[1]))
732 *offp = off - offsetof(struct bpt, instr[0]);
733 return (struct bpt *) (nip - off);
736 static struct bpt *new_breakpoint(unsigned long a)
741 bp = at_breakpoint(a);
745 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
746 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
748 bp->instr[1] = bpinstr;
749 store_inst(&bp->instr[1]);
754 printf("Sorry, no free breakpoints. Please clear one first.\n");
758 static void insert_bpts(void)
764 for (i = 0; i < NBPTS; ++i, ++bp) {
765 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
767 if (mread(bp->address, &bp->instr[0], 4) != 4) {
768 printf("Couldn't read instruction at %lx, "
769 "disabling breakpoint there\n", bp->address);
773 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
774 printf("Breakpoint at %lx is on an mtmsrd or rfid "
775 "instruction, disabling it\n", bp->address);
779 store_inst(&bp->instr[0]);
780 if (bp->enabled & BP_CIABR)
782 if (mwrite(bp->address, &bpinstr, 4) != 4) {
783 printf("Couldn't write instruction at %lx, "
784 "disabling breakpoint there\n", bp->address);
785 bp->enabled &= ~BP_TRAP;
788 store_inst((void *)bp->address);
792 static void insert_cpu_bpts(void)
794 struct arch_hw_breakpoint brk;
797 brk.address = dabr.address;
798 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
800 __set_breakpoint(&brk);
804 set_ciabr(iabr->address);
807 static void remove_bpts(void)
814 for (i = 0; i < NBPTS; ++i, ++bp) {
815 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
817 if (mread(bp->address, &instr, 4) == 4
819 && mwrite(bp->address, &bp->instr, 4) != 4)
820 printf("Couldn't remove breakpoint at %lx\n",
823 store_inst((void *)bp->address);
827 static void remove_cpu_bpts(void)
829 hw_breakpoint_disable();
833 static void set_lpp_cmd(void)
837 if (!scanhex(&lpp)) {
838 printf("Invalid number.\n");
841 xmon_set_pagination_lpp(lpp);
843 /* Command interpreting routine */
844 static char *last_cmd;
847 cmds(struct pt_regs *excp)
854 if (!xmon_no_auto_backtrace) {
855 xmon_no_auto_backtrace = 1;
856 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
861 printf("%x:", smp_processor_id());
862 #endif /* CONFIG_SMP */
868 if (last_cmd == NULL)
870 take_input(last_cmd);
904 prregs(excp); /* print regs */
919 if (do_spu_cmd() == 0)
928 printf(" <no input ...>\n");
932 xmon_puts(help_string);
953 #ifdef CONFIG_PPC_STD_MMU
957 #elif defined(CONFIG_44x)
961 #elif defined(CONFIG_PPC_BOOK3E)
967 printf("Unrecognized command: ");
969 if (' ' < cmd && cmd <= '~')
972 printf("\\x%x", cmd);
974 } while (cmd != '\n');
975 printf(" (type ? for help)\n");
982 static int do_step(struct pt_regs *regs)
985 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
990 * Step a single instruction.
991 * Some instructions we emulate, others we execute with MSR_SE set.
993 static int do_step(struct pt_regs *regs)
998 /* check we are in 64-bit kernel mode, translation enabled */
999 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1000 if (mread(regs->nip, &instr, 4) == 4) {
1001 stepped = emulate_step(regs, instr);
1003 printf("Couldn't single-step %s instruction\n",
1004 (IS_RFID(instr)? "rfid": "mtmsrd"));
1008 regs->trap = 0xd00 | (regs->trap & 1);
1009 printf("stepped to ");
1010 xmon_print_symbol(regs->nip, " ", "\n");
1011 ppc_inst_dump(regs->nip, 1, 0);
1016 regs->msr |= MSR_SE;
1021 static void bootcmds(void)
1027 ppc_md.restart(NULL);
1028 else if (cmd == 'h')
1030 else if (cmd == 'p')
1035 static int cpu_cmd(void)
1038 unsigned long cpu, first_cpu, last_cpu;
1041 if (!scanhex(&cpu)) {
1042 /* print cpus waiting or in xmon */
1043 printf("cpus stopped:");
1044 last_cpu = first_cpu = NR_CPUS;
1045 for_each_possible_cpu(cpu) {
1046 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1047 if (cpu == last_cpu + 1) {
1050 if (last_cpu != first_cpu)
1051 printf("-0x%lx", last_cpu);
1052 last_cpu = first_cpu = cpu;
1053 printf(" 0x%lx", cpu);
1057 if (last_cpu != first_cpu)
1058 printf("-0x%lx", last_cpu);
1062 /* try to switch to cpu specified */
1063 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1064 printf("cpu 0x%x isn't in xmon\n", cpu);
1071 while (!xmon_taken) {
1072 if (--timeout == 0) {
1073 if (test_and_set_bit(0, &xmon_taken))
1075 /* take control back */
1077 xmon_owner = smp_processor_id();
1078 printf("cpu 0x%x didn't take control\n", cpu);
1086 #endif /* CONFIG_SMP */
1089 static unsigned short fcstab[256] = {
1090 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1091 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1092 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1093 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1094 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1095 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1096 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1097 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1098 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1099 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1100 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1101 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1102 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1103 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1104 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1105 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1106 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1107 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1108 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1109 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1110 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1111 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1112 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1113 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1114 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1115 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1116 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1117 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1118 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1119 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1120 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1121 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1124 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1133 if (!scanhex(&adrs))
1135 if (!scanhex(&ncsum))
1138 for (i = 0; i < ncsum; ++i) {
1139 if (mread(adrs+i, &v, 1) == 0) {
1140 printf("csum stopped at "REG"\n", adrs+i);
1145 printf("%x\n", fcs);
1149 * Check if this is a suitable place to put a breakpoint.
1151 static long check_bp_loc(unsigned long addr)
1156 if (!is_kernel_addr(addr)) {
1157 printf("Breakpoints may only be placed at kernel addresses\n");
1160 if (!mread(addr, &instr, sizeof(instr))) {
1161 printf("Can't read instruction at address %lx\n", addr);
1164 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1165 printf("Breakpoints may not be placed on mtmsrd or rfid "
1172 static char *breakpoint_help_string =
1173 "Breakpoint command usage:\n"
1174 "b show breakpoints\n"
1175 "b <addr> [cnt] set breakpoint at given instr addr\n"
1176 "bc clear all breakpoints\n"
1177 "bc <n/addr> clear breakpoint number n or at addr\n"
1178 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1179 "bd <addr> [cnt] set hardware data breakpoint\n"
1189 const char badaddr[] = "Only kernel addresses are permitted "
1190 "for breakpoints\n";
1195 case 'd': /* bd - hardware data breakpoint */
1200 else if (cmd == 'w')
1206 if (scanhex(&dabr.address)) {
1207 if (!is_kernel_addr(dabr.address)) {
1211 dabr.address &= ~HW_BRK_TYPE_DABR;
1212 dabr.enabled = mode | BP_DABR;
1216 case 'i': /* bi - hardware instr breakpoint */
1217 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1218 printf("Hardware instruction breakpoint "
1219 "not supported on this cpu\n");
1223 iabr->enabled &= ~BP_CIABR;
1228 if (!check_bp_loc(a))
1230 bp = new_breakpoint(a);
1232 bp->enabled |= BP_CIABR;
1240 /* clear all breakpoints */
1241 for (i = 0; i < NBPTS; ++i)
1242 bpts[i].enabled = 0;
1245 printf("All breakpoints cleared\n");
1249 if (a <= NBPTS && a >= 1) {
1250 /* assume a breakpoint number */
1251 bp = &bpts[a-1]; /* bp nums are 1 based */
1253 /* assume a breakpoint address */
1254 bp = at_breakpoint(a);
1256 printf("No breakpoint at %lx\n", a);
1261 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1262 xmon_print_symbol(bp->address, " ", ")\n");
1270 printf(breakpoint_help_string);
1275 /* print all breakpoints */
1276 printf(" type address\n");
1278 printf(" data "REG" [", dabr.address);
1279 if (dabr.enabled & 1)
1281 if (dabr.enabled & 2)
1285 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1288 printf("%2x %s ", BP_NUM(bp),
1289 (bp->enabled & BP_CIABR) ? "inst": "trap");
1290 xmon_print_symbol(bp->address, " ", "\n");
1295 if (!check_bp_loc(a))
1297 bp = new_breakpoint(a);
1299 bp->enabled |= BP_TRAP;
1304 /* Very cheap human name for vector lookup. */
1306 const char *getvecname(unsigned long vec)
1311 case 0x100: ret = "(System Reset)"; break;
1312 case 0x200: ret = "(Machine Check)"; break;
1313 case 0x300: ret = "(Data Access)"; break;
1314 case 0x380: ret = "(Data SLB Access)"; break;
1315 case 0x400: ret = "(Instruction Access)"; break;
1316 case 0x480: ret = "(Instruction SLB Access)"; break;
1317 case 0x500: ret = "(Hardware Interrupt)"; break;
1318 case 0x600: ret = "(Alignment)"; break;
1319 case 0x700: ret = "(Program Check)"; break;
1320 case 0x800: ret = "(FPU Unavailable)"; break;
1321 case 0x900: ret = "(Decrementer)"; break;
1322 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1323 case 0xa00: ret = "(Doorbell)"; break;
1324 case 0xc00: ret = "(System Call)"; break;
1325 case 0xd00: ret = "(Single Step)"; break;
1326 case 0xe40: ret = "(Emulation Assist)"; break;
1327 case 0xe60: ret = "(HMI)"; break;
1328 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1329 case 0xf00: ret = "(Performance Monitor)"; break;
1330 case 0xf20: ret = "(Altivec Unavailable)"; break;
1331 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1332 case 0x1500: ret = "(Denormalisation)"; break;
1333 case 0x1700: ret = "(Altivec Assist)"; break;
1339 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1340 unsigned long *endp)
1342 unsigned long size, offset;
1345 *startp = *endp = 0;
1348 if (setjmp(bus_error_jmp) == 0) {
1349 catch_memory_errors = 1;
1351 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1353 *startp = pc - offset;
1354 *endp = pc - offset + size;
1358 catch_memory_errors = 0;
1361 #define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1362 #define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1364 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1367 int max_to_print = 64;
1369 unsigned long newsp;
1370 unsigned long marker;
1371 struct pt_regs regs;
1373 while (max_to_print--) {
1374 if (sp < PAGE_OFFSET) {
1376 printf("SP (%lx) is in userspace\n", sp);
1380 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1381 || !mread(sp, &newsp, sizeof(unsigned long))) {
1382 printf("Couldn't read stack frame at %lx\n", sp);
1387 * For the first stack frame, try to work out if
1388 * LR and/or the saved LR value in the bottommost
1389 * stack frame are valid.
1391 if ((pc | lr) != 0) {
1392 unsigned long fnstart, fnend;
1393 unsigned long nextip;
1396 get_function_bounds(pc, &fnstart, &fnend);
1399 mread(newsp + LRSAVE_OFFSET, &nextip,
1400 sizeof(unsigned long));
1402 if (lr < PAGE_OFFSET
1403 || (fnstart <= lr && lr < fnend))
1405 } else if (lr == nextip) {
1407 } else if (lr >= PAGE_OFFSET
1408 && !(fnstart <= lr && lr < fnend)) {
1409 printf("[link register ] ");
1410 xmon_print_symbol(lr, " ", "\n");
1413 printf("["REG"] ", sp);
1414 xmon_print_symbol(ip, " ", " (unreliable)\n");
1419 printf("["REG"] ", sp);
1420 xmon_print_symbol(ip, " ", "\n");
1423 /* Look for "regshere" marker to see if this is
1424 an exception frame. */
1425 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1426 && marker == STACK_FRAME_REGS_MARKER) {
1427 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1429 printf("Couldn't read registers at %lx\n",
1430 sp + STACK_FRAME_OVERHEAD);
1433 printf("--- Exception: %lx %s at ", regs.trap,
1434 getvecname(TRAP(®s)));
1437 xmon_print_symbol(pc, " ", "\n");
1447 static void backtrace(struct pt_regs *excp)
1452 xmon_show_stack(sp, 0, 0);
1454 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1458 static void print_bug_trap(struct pt_regs *regs)
1461 const struct bug_entry *bug;
1464 if (regs->msr & MSR_PR)
1465 return; /* not in kernel */
1466 addr = regs->nip; /* address of trap instruction */
1467 if (addr < PAGE_OFFSET)
1469 bug = find_bug(regs->nip);
1472 if (is_warning_bug(bug))
1475 #ifdef CONFIG_DEBUG_BUGVERBOSE
1476 printf("kernel BUG at %s:%u!\n",
1477 bug->file, bug->line);
1479 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1481 #endif /* CONFIG_BUG */
1484 static void excprint(struct pt_regs *fp)
1489 printf("cpu 0x%x: ", smp_processor_id());
1490 #endif /* CONFIG_SMP */
1493 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1495 xmon_print_symbol(fp->nip, ": ", "\n");
1497 printf(" lr: ", fp->link);
1498 xmon_print_symbol(fp->link, ": ", "\n");
1500 printf(" sp: %lx\n", fp->gpr[1]);
1501 printf(" msr: %lx\n", fp->msr);
1503 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1504 printf(" dar: %lx\n", fp->dar);
1506 printf(" dsisr: %lx\n", fp->dsisr);
1509 printf(" current = 0x%lx\n", current);
1511 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1512 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1515 printf(" pid = %ld, comm = %s\n",
1516 current->pid, current->comm);
1522 printf(linux_banner);
1525 static void prregs(struct pt_regs *fp)
1529 struct pt_regs regs;
1531 if (scanhex(&base)) {
1532 if (setjmp(bus_error_jmp) == 0) {
1533 catch_memory_errors = 1;
1535 regs = *(struct pt_regs *)base;
1539 catch_memory_errors = 0;
1540 printf("*** Error reading registers from "REG"\n",
1544 catch_memory_errors = 0;
1549 if (FULL_REGS(fp)) {
1550 for (n = 0; n < 16; ++n)
1551 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1552 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1554 for (n = 0; n < 7; ++n)
1555 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1556 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1559 for (n = 0; n < 32; ++n) {
1560 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1561 (n & 3) == 3? "\n": " ");
1562 if (n == 12 && !FULL_REGS(fp)) {
1569 xmon_print_symbol(fp->nip, " ", "\n");
1570 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1572 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1575 xmon_print_symbol(fp->link, " ", "\n");
1576 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1577 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1578 fp->ctr, fp->xer, fp->trap);
1580 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1581 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1584 static void cacheflush(void)
1587 unsigned long nflush;
1592 scanhex((void *)&adrs);
1597 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1598 if (setjmp(bus_error_jmp) == 0) {
1599 catch_memory_errors = 1;
1603 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1604 cflush((void *) adrs);
1606 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1607 cinval((void *) adrs);
1610 /* wait a little while to see if we get a machine check */
1613 catch_memory_errors = 0;
1616 static unsigned long
1619 unsigned int instrs[2];
1620 unsigned long (*code)(void);
1621 unsigned long ret = -1UL;
1623 unsigned long opd[3];
1625 opd[0] = (unsigned long)instrs;
1628 code = (unsigned long (*)(void)) opd;
1630 code = (unsigned long (*)(void)) instrs;
1633 /* mfspr r3,n; blr */
1634 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1635 instrs[1] = 0x4e800020;
1637 store_inst(instrs+1);
1639 if (setjmp(bus_error_jmp) == 0) {
1640 catch_memory_errors = 1;
1646 /* wait a little while to see if we get a machine check */
1655 write_spr(int n, unsigned long val)
1657 unsigned int instrs[2];
1658 unsigned long (*code)(unsigned long);
1660 unsigned long opd[3];
1662 opd[0] = (unsigned long)instrs;
1665 code = (unsigned long (*)(unsigned long)) opd;
1667 code = (unsigned long (*)(unsigned long)) instrs;
1670 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1671 instrs[1] = 0x4e800020;
1673 store_inst(instrs+1);
1675 if (setjmp(bus_error_jmp) == 0) {
1676 catch_memory_errors = 1;
1682 /* wait a little while to see if we get a machine check */
1688 static unsigned long regno;
1689 extern char exc_prolog;
1690 extern char dec_exc;
1692 static void super_regs(void)
1699 unsigned long sp, toc;
1700 asm("mr %0,1" : "=r" (sp) :);
1701 asm("mr %0,2" : "=r" (toc) :);
1703 printf("msr = "REG" sprg0= "REG"\n",
1704 mfmsr(), mfspr(SPRN_SPRG0));
1705 printf("pvr = "REG" sprg1= "REG"\n",
1706 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1707 printf("dec = "REG" sprg2= "REG"\n",
1708 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1709 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1710 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1718 val = read_spr(regno);
1720 write_spr(regno, val);
1723 printf("spr %lx = %lx\n", regno, read_spr(regno));
1730 * Stuff for reading and writing memory safely
1733 mread(unsigned long adrs, void *buf, int size)
1739 if (setjmp(bus_error_jmp) == 0) {
1740 catch_memory_errors = 1;
1746 *(u16 *)q = *(u16 *)p;
1749 *(u32 *)q = *(u32 *)p;
1752 *(u64 *)q = *(u64 *)p;
1755 for( ; n < size; ++n) {
1761 /* wait a little while to see if we get a machine check */
1765 catch_memory_errors = 0;
1770 mwrite(unsigned long adrs, void *buf, int size)
1776 if (setjmp(bus_error_jmp) == 0) {
1777 catch_memory_errors = 1;
1783 *(u16 *)p = *(u16 *)q;
1786 *(u32 *)p = *(u32 *)q;
1789 *(u64 *)p = *(u64 *)q;
1792 for ( ; n < size; ++n) {
1798 /* wait a little while to see if we get a machine check */
1802 printf("*** Error writing address "REG"\n", adrs + n);
1804 catch_memory_errors = 0;
1808 static int fault_type;
1809 static int fault_except;
1810 static char *fault_chars[] = { "--", "**", "##" };
1812 static int handle_fault(struct pt_regs *regs)
1814 fault_except = TRAP(regs);
1815 switch (TRAP(regs)) {
1827 longjmp(bus_error_jmp, 1);
1832 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1835 byterev(unsigned char *val, int size)
1841 SWAP(val[0], val[1], t);
1844 SWAP(val[0], val[3], t);
1845 SWAP(val[1], val[2], t);
1847 case 8: /* is there really any use for this? */
1848 SWAP(val[0], val[7], t);
1849 SWAP(val[1], val[6], t);
1850 SWAP(val[2], val[5], t);
1851 SWAP(val[3], val[4], t);
1859 static char *memex_help_string =
1860 "Memory examine command usage:\n"
1861 "m [addr] [flags] examine/change memory\n"
1862 " addr is optional. will start where left off.\n"
1863 " flags may include chars from this set:\n"
1864 " b modify by bytes (default)\n"
1865 " w modify by words (2 byte)\n"
1866 " l modify by longs (4 byte)\n"
1867 " d modify by doubleword (8 byte)\n"
1868 " r toggle reverse byte order mode\n"
1869 " n do not read memory (for i/o spaces)\n"
1870 " . ok to read (default)\n"
1871 "NOTE: flags are saved as defaults\n"
1874 static char *memex_subcmd_help_string =
1875 "Memory examine subcommands:\n"
1876 " hexval write this val to current location\n"
1877 " 'string' write chars from string to this location\n"
1878 " ' increment address\n"
1879 " ^ decrement address\n"
1880 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1881 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1882 " ` clear no-read flag\n"
1883 " ; stay at this addr\n"
1884 " v change to byte mode\n"
1885 " w change to word (2 byte) mode\n"
1886 " l change to long (4 byte) mode\n"
1887 " u change to doubleword (8 byte) mode\n"
1888 " m addr change current addr\n"
1889 " n toggle no-read flag\n"
1890 " r toggle byte reverse flag\n"
1891 " < count back up count bytes\n"
1892 " > count skip forward count bytes\n"
1893 " x exit this mode\n"
1899 int cmd, inc, i, nslash;
1901 unsigned char val[16];
1903 scanhex((void *)&adrs);
1906 printf(memex_help_string);
1912 while ((cmd = skipbl()) != '\n') {
1914 case 'b': size = 1; break;
1915 case 'w': size = 2; break;
1916 case 'l': size = 4; break;
1917 case 'd': size = 8; break;
1918 case 'r': brev = !brev; break;
1919 case 'n': mnoread = 1; break;
1920 case '.': mnoread = 0; break;
1929 n = mread(adrs, val, size);
1930 printf(REG"%c", adrs, brev? 'r': ' ');
1935 for (i = 0; i < n; ++i)
1936 printf("%.2x", val[i]);
1937 for (; i < size; ++i)
1938 printf("%s", fault_chars[fault_type]);
1945 for (i = 0; i < size; ++i)
1946 val[i] = n >> (i * 8);
1949 mwrite(adrs, val, size);
1962 else if( n == '\'' )
1964 for (i = 0; i < size; ++i)
1965 val[i] = n >> (i * 8);
1968 mwrite(adrs, val, size);
2004 adrs -= 1 << nslash;
2008 adrs += 1 << nslash;
2012 adrs += 1 << -nslash;
2016 adrs -= 1 << -nslash;
2019 scanhex((void *)&adrs);
2038 printf(memex_subcmd_help_string);
2053 case 'n': c = '\n'; break;
2054 case 'r': c = '\r'; break;
2055 case 'b': c = '\b'; break;
2056 case 't': c = '\t'; break;
2061 static void xmon_rawdump (unsigned long adrs, long ndump)
2064 unsigned char temp[16];
2066 for (n = ndump; n > 0;) {
2068 nr = mread(adrs, temp, r);
2070 for (m = 0; m < r; ++m) {
2072 printf("%.2x", temp[m]);
2074 printf("%s", fault_chars[fault_type]);
2084 static void dump_one_paca(int cpu)
2086 struct paca_struct *p;
2087 #ifdef CONFIG_PPC_STD_MMU_64
2091 if (setjmp(bus_error_jmp) != 0) {
2092 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2096 catch_memory_errors = 1;
2101 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2103 printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu) ? "yes" : "no");
2104 printf(" %-*s = %s\n", 20, "present", cpu_present(cpu) ? "yes" : "no");
2105 printf(" %-*s = %s\n", 20, "online", cpu_online(cpu) ? "yes" : "no");
2107 #define DUMP(paca, name, format) \
2108 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
2109 offsetof(struct paca_struct, name));
2111 DUMP(p, lock_token, "x");
2112 DUMP(p, paca_index, "x");
2113 DUMP(p, kernel_toc, "lx");
2114 DUMP(p, kernelbase, "lx");
2115 DUMP(p, kernel_msr, "lx");
2116 DUMP(p, emergency_sp, "p");
2117 #ifdef CONFIG_PPC_BOOK3S_64
2118 DUMP(p, mc_emergency_sp, "p");
2119 DUMP(p, in_mce, "x");
2120 DUMP(p, hmi_event_available, "x");
2122 DUMP(p, data_offset, "lx");
2123 DUMP(p, hw_cpu_id, "x");
2124 DUMP(p, cpu_start, "x");
2125 DUMP(p, kexec_state, "x");
2126 #ifdef CONFIG_PPC_STD_MMU_64
2127 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2130 if (!p->slb_shadow_ptr)
2133 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2134 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2137 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2141 DUMP(p, vmalloc_sllp, "x");
2142 DUMP(p, slb_cache_ptr, "x");
2143 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2144 printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]);
2146 DUMP(p, dscr_default, "llx");
2147 #ifdef CONFIG_PPC_BOOK3E
2149 DUMP(p, kernel_pgd, "p");
2150 DUMP(p, tcd_ptr, "p");
2151 DUMP(p, mc_kstack, "p");
2152 DUMP(p, crit_kstack, "p");
2153 DUMP(p, dbg_kstack, "p");
2155 DUMP(p, __current, "p");
2156 DUMP(p, kstack, "lx");
2157 DUMP(p, stab_rr, "lx");
2158 DUMP(p, saved_r1, "lx");
2159 DUMP(p, trap_save, "x");
2160 DUMP(p, soft_enabled, "x");
2161 DUMP(p, irq_happened, "x");
2162 DUMP(p, io_sync, "x");
2163 DUMP(p, irq_work_pending, "x");
2164 DUMP(p, nap_state_lost, "x");
2165 DUMP(p, sprg_vdso, "llx");
2167 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2168 DUMP(p, tm_scratch, "llx");
2171 #ifdef CONFIG_PPC_POWERNV
2172 DUMP(p, core_idle_state_ptr, "p");
2173 DUMP(p, thread_idle_state, "x");
2174 DUMP(p, thread_mask, "x");
2175 DUMP(p, subcore_sibling_mask, "x");
2178 DUMP(p, user_time, "llx");
2179 DUMP(p, system_time, "llx");
2180 DUMP(p, user_time_scaled, "llx");
2181 DUMP(p, starttime, "llx");
2182 DUMP(p, starttime_user, "llx");
2183 DUMP(p, startspurr, "llx");
2184 DUMP(p, utime_sspurr, "llx");
2185 DUMP(p, stolen_time, "llx");
2188 catch_memory_errors = 0;
2192 static void dump_all_pacas(void)
2196 if (num_possible_cpus() == 0) {
2197 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2201 for_each_possible_cpu(cpu)
2205 static void dump_pacas(void)
2216 termch = c; /* Put c back, it wasn't 'a' */
2221 dump_one_paca(xmon_owner);
2234 xmon_start_pagination();
2236 xmon_end_pagination();
2241 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2243 scanhex((void *)&adrs);
2250 else if (nidump > MAX_DUMP)
2252 adrs += ppc_inst_dump(adrs, nidump, 1);
2254 } else if (c == 'l') {
2256 } else if (c == 'r') {
2260 xmon_rawdump(adrs, ndump);
2267 else if (ndump > MAX_DUMP)
2269 prdump(adrs, ndump);
2276 prdump(unsigned long adrs, long ndump)
2278 long n, m, c, r, nr;
2279 unsigned char temp[16];
2281 for (n = ndump; n > 0;) {
2285 nr = mread(adrs, temp, r);
2287 for (m = 0; m < r; ++m) {
2288 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2291 printf("%.2x", temp[m]);
2293 printf("%s", fault_chars[fault_type]);
2295 for (; m < 16; ++m) {
2296 if ((m & (sizeof(long) - 1)) == 0)
2301 for (m = 0; m < r; ++m) {
2304 putchar(' ' <= c && c <= '~'? c: '.');
2317 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2320 generic_inst_dump(unsigned long adr, long count, int praddr,
2321 instruction_dump_func dump_func)
2324 unsigned long first_adr;
2325 unsigned long inst, last_inst = 0;
2326 unsigned char val[4];
2329 for (first_adr = adr; count > 0; --count, adr += 4) {
2330 nr = mread(adr, val, 4);
2333 const char *x = fault_chars[fault_type];
2334 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2338 inst = GETWORD(val);
2339 if (adr > first_adr && inst == last_inst) {
2349 printf(REG" %.8x", adr, inst);
2351 dump_func(inst, adr);
2354 return adr - first_adr;
2358 ppc_inst_dump(unsigned long adr, long count, int praddr)
2360 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2364 print_address(unsigned long addr)
2366 xmon_print_symbol(addr, "\t# ", "");
2372 struct kmsg_dumper dumper = { .active = 1 };
2373 unsigned char buf[128];
2376 if (setjmp(bus_error_jmp) != 0) {
2377 printf("Error dumping printk buffer!\n");
2381 catch_memory_errors = 1;
2384 kmsg_dump_rewind_nolock(&dumper);
2385 xmon_start_pagination();
2386 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2390 xmon_end_pagination();
2393 /* wait a little while to see if we get a machine check */
2395 catch_memory_errors = 0;
2399 * Memory operations - move, set, print differences
2401 static unsigned long mdest; /* destination address */
2402 static unsigned long msrc; /* source address */
2403 static unsigned long mval; /* byte value to set memory to */
2404 static unsigned long mcount; /* # bytes to affect */
2405 static unsigned long mdiffs; /* max # differences to print */
2410 scanhex((void *)&mdest);
2411 if( termch != '\n' )
2413 scanhex((void *)(cmd == 's'? &mval: &msrc));
2414 if( termch != '\n' )
2416 scanhex((void *)&mcount);
2419 memmove((void *)mdest, (void *)msrc, mcount);
2422 memset((void *)mdest, mval, mcount);
2425 if( termch != '\n' )
2427 scanhex((void *)&mdiffs);
2428 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2434 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2439 for( n = nb; n > 0; --n )
2440 if( *p1++ != *p2++ )
2441 if( ++prt <= maxpr )
2442 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2443 p1[-1], p2 - 1, p2[-1]);
2445 printf("Total of %d differences\n", prt);
2448 static unsigned mend;
2449 static unsigned mask;
2455 unsigned char val[4];
2458 scanhex((void *)&mdest);
2459 if (termch != '\n') {
2461 scanhex((void *)&mend);
2462 if (termch != '\n') {
2464 scanhex((void *)&mval);
2466 if (termch != '\n') termch = 0;
2467 scanhex((void *)&mask);
2471 for (a = mdest; a < mend; a += 4) {
2472 if (mread(a, val, 4) == 4
2473 && ((GETWORD(val) ^ mval) & mask) == 0) {
2474 printf("%.16x: %.16x\n", a, GETWORD(val));
2481 static unsigned long mskip = 0x1000;
2482 static unsigned long mlim = 0xffffffff;
2492 if (termch != '\n') termch = 0;
2494 if (termch != '\n') termch = 0;
2497 for (a = mdest; a < mlim; a += mskip) {
2498 ok = mread(a, &v, 1);
2500 printf("%.8x .. ", a);
2501 } else if (!ok && ook)
2502 printf("%.8x\n", a - mskip);
2508 printf("%.8x\n", a - mskip);
2511 static void proccall(void)
2513 unsigned long args[8];
2516 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2517 unsigned long, unsigned long, unsigned long,
2518 unsigned long, unsigned long, unsigned long);
2521 if (!scanhex(&adrs))
2525 for (i = 0; i < 8; ++i)
2527 for (i = 0; i < 8; ++i) {
2528 if (!scanhex(&args[i]) || termch == '\n')
2532 func = (callfunc_t) adrs;
2534 if (setjmp(bus_error_jmp) == 0) {
2535 catch_memory_errors = 1;
2537 ret = func(args[0], args[1], args[2], args[3],
2538 args[4], args[5], args[6], args[7]);
2540 printf("return value is 0x%lx\n", ret);
2542 printf("*** %x exception occurred\n", fault_except);
2544 catch_memory_errors = 0;
2547 /* Input scanning routines */
2558 while( c == ' ' || c == '\t' )
2564 static char *regnames[N_PTREGS] = {
2565 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2566 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2567 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2568 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2569 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2575 "trap", "dar", "dsisr", "res"
2579 scanhex(unsigned long *vp)
2586 /* parse register name */
2590 for (i = 0; i < sizeof(regname) - 1; ++i) {
2599 for (i = 0; i < N_PTREGS; ++i) {
2600 if (strcmp(regnames[i], regname) == 0) {
2601 if (xmon_regs == NULL) {
2602 printf("regs not available\n");
2605 *vp = ((unsigned long *)xmon_regs)[i];
2609 printf("invalid register name '%%%s'\n", regname);
2613 /* skip leading "0x" if any */
2627 } else if (c == '$') {
2629 for (i=0; i<63; i++) {
2631 if (isspace(c) || c == '\0') {
2639 if (setjmp(bus_error_jmp) == 0) {
2640 catch_memory_errors = 1;
2642 *vp = kallsyms_lookup_name(tmpstr);
2645 catch_memory_errors = 0;
2647 printf("unknown symbol '%s'\n", tmpstr);
2680 static int hexdigit(int c)
2682 if( '0' <= c && c <= '9' )
2684 if( 'A' <= c && c <= 'F' )
2685 return c - ('A' - 10);
2686 if( 'a' <= c && c <= 'f' )
2687 return c - ('a' - 10);
2692 getstring(char *s, int size)
2703 } while( c != ' ' && c != '\t' && c != '\n' );
2708 static char line[256];
2709 static char *lineptr;
2720 if (lineptr == NULL || *lineptr == 0) {
2721 if (xmon_gets(line, sizeof(line)) == NULL) {
2731 take_input(char *str)
2740 int type = inchar();
2742 static char tmp[64];
2747 xmon_print_symbol(addr, ": ", "\n");
2752 if (setjmp(bus_error_jmp) == 0) {
2753 catch_memory_errors = 1;
2755 addr = kallsyms_lookup_name(tmp);
2757 printf("%s: %lx\n", tmp, addr);
2759 printf("Symbol '%s' not found.\n", tmp);
2762 catch_memory_errors = 0;
2769 /* Print an address in numeric and symbolic form (if possible) */
2770 static void xmon_print_symbol(unsigned long address, const char *mid,
2774 const char *name = NULL;
2775 unsigned long offset, size;
2777 printf(REG, address);
2778 if (setjmp(bus_error_jmp) == 0) {
2779 catch_memory_errors = 1;
2781 name = kallsyms_lookup(address, &size, &offset, &modname,
2784 /* wait a little while to see if we get a machine check */
2788 catch_memory_errors = 0;
2791 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2793 printf(" [%s]", modname);
2795 printf("%s", after);
2798 #ifdef CONFIG_PPC_BOOK3S_64
2799 void dump_segments(void)
2802 unsigned long esid,vsid;
2805 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2807 for (i = 0; i < mmu_slb_size; i++) {
2808 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2809 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2811 printf("%02d %016lx %016lx", i, esid, vsid);
2812 if (esid & SLB_ESID_V) {
2813 llp = vsid & SLB_VSID_LLP;
2814 if (vsid & SLB_VSID_B_1T) {
2815 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2817 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2820 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2822 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2832 #ifdef CONFIG_PPC_STD_MMU_32
2833 void dump_segments(void)
2838 for (i = 0; i < 16; ++i)
2839 printf(" %x", mfsrin(i));
2845 static void dump_tlb_44x(void)
2849 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2850 unsigned long w0,w1,w2;
2851 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2852 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2853 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2854 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2855 if (w0 & PPC44x_TLB_VALID) {
2856 printf("V %08x -> %01x%08x %c%c%c%c%c",
2857 w0 & PPC44x_TLB_EPN_MASK,
2858 w1 & PPC44x_TLB_ERPN_MASK,
2859 w1 & PPC44x_TLB_RPN_MASK,
2860 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2861 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2862 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2863 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2864 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2869 #endif /* CONFIG_44x */
2871 #ifdef CONFIG_PPC_BOOK3E
2872 static void dump_tlb_book3e(void)
2874 u32 mmucfg, pidmask, lpidmask;
2876 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2878 static const char *pgsz_names[] = {
2913 /* Gather some infos about the MMU */
2914 mmucfg = mfspr(SPRN_MMUCFG);
2915 mmu_version = (mmucfg & 3) + 1;
2916 ntlbs = ((mmucfg >> 2) & 3) + 1;
2917 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2918 lpidsz = (mmucfg >> 24) & 0xf;
2919 rasz = (mmucfg >> 16) & 0x7f;
2920 if ((mmu_version > 1) && (mmucfg & 0x10000))
2922 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2923 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2924 pidmask = (1ul << pidsz) - 1;
2925 lpidmask = (1ul << lpidsz) - 1;
2926 ramask = (1ull << rasz) - 1;
2928 for (tlb = 0; tlb < ntlbs; tlb++) {
2930 int nent, assoc, new_cc = 1;
2931 printf("TLB %d:\n------\n", tlb);
2934 tlbcfg = mfspr(SPRN_TLB0CFG);
2937 tlbcfg = mfspr(SPRN_TLB1CFG);
2940 tlbcfg = mfspr(SPRN_TLB2CFG);
2943 tlbcfg = mfspr(SPRN_TLB3CFG);
2946 printf("Unsupported TLB number !\n");
2949 nent = tlbcfg & 0xfff;
2950 assoc = (tlbcfg >> 24) & 0xff;
2951 for (i = 0; i < nent; i++) {
2952 u32 mas0 = MAS0_TLBSEL(tlb);
2953 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2956 int esel = i, cc = i;
2964 mas0 |= MAS0_ESEL(esel);
2965 mtspr(SPRN_MAS0, mas0);
2966 mtspr(SPRN_MAS1, mas1);
2967 mtspr(SPRN_MAS2, mas2);
2968 asm volatile("tlbre 0,0,0" : : : "memory");
2969 mas1 = mfspr(SPRN_MAS1);
2970 mas2 = mfspr(SPRN_MAS2);
2971 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2972 if (assoc && (i % assoc) == 0)
2974 if (!(mas1 & MAS1_VALID))
2977 printf("%04x- ", i);
2979 printf("%04x-%c", cc, 'A' + esel);
2981 printf(" |%c", 'A' + esel);
2983 printf(" %016llx %04x %s %c%c AS%c",
2985 (mas1 >> 16) & 0x3fff,
2986 pgsz_names[(mas1 >> 7) & 0x1f],
2987 mas1 & MAS1_IND ? 'I' : ' ',
2988 mas1 & MAS1_IPROT ? 'P' : ' ',
2989 mas1 & MAS1_TS ? '1' : '0');
2990 printf(" %c%c%c%c%c%c%c",
2991 mas2 & MAS2_X0 ? 'a' : ' ',
2992 mas2 & MAS2_X1 ? 'v' : ' ',
2993 mas2 & MAS2_W ? 'w' : ' ',
2994 mas2 & MAS2_I ? 'i' : ' ',
2995 mas2 & MAS2_M ? 'm' : ' ',
2996 mas2 & MAS2_G ? 'g' : ' ',
2997 mas2 & MAS2_E ? 'e' : ' ');
2998 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2999 if (mas1 & MAS1_IND)
3001 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3003 printf(" U%c%c%c S%c%c%c\n",
3004 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3005 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3006 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3007 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3008 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3009 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3013 #endif /* CONFIG_PPC_BOOK3E */
3015 static void xmon_init(int enable)
3019 __debugger_ipi = xmon_ipi;
3020 __debugger_bpt = xmon_bpt;
3021 __debugger_sstep = xmon_sstep;
3022 __debugger_iabr_match = xmon_iabr_match;
3023 __debugger_break_match = xmon_break_match;
3024 __debugger_fault_handler = xmon_fault_handler;
3027 __debugger_ipi = NULL;
3028 __debugger_bpt = NULL;
3029 __debugger_sstep = NULL;
3030 __debugger_iabr_match = NULL;
3031 __debugger_break_match = NULL;
3032 __debugger_fault_handler = NULL;
3036 #ifdef CONFIG_MAGIC_SYSRQ
3037 static void sysrq_handle_xmon(int key)
3039 /* ensure xmon is enabled */
3041 debugger(get_irq_regs());
3044 static struct sysrq_key_op sysrq_xmon_op = {
3045 .handler = sysrq_handle_xmon,
3046 .help_msg = "xmon(x)",
3047 .action_msg = "Entering xmon",
3050 static int __init setup_xmon_sysrq(void)
3052 register_sysrq_key('x', &sysrq_xmon_op);
3055 __initcall(setup_xmon_sysrq);
3056 #endif /* CONFIG_MAGIC_SYSRQ */
3058 static int __initdata xmon_early, xmon_off;
3060 static int __init early_parse_xmon(char *p)
3062 if (!p || strncmp(p, "early", 5) == 0) {
3063 /* just "xmon" is equivalent to "xmon=early" */
3066 } else if (strncmp(p, "on", 2) == 0)
3068 else if (strncmp(p, "off", 3) == 0)
3070 else if (strncmp(p, "nobt", 4) == 0)
3071 xmon_no_auto_backtrace = 1;
3077 early_param("xmon", early_parse_xmon);
3079 void __init xmon_setup(void)
3081 #ifdef CONFIG_XMON_DEFAULT
3089 #ifdef CONFIG_SPU_BASE
3093 u64 saved_mfc_sr1_RW;
3094 u32 saved_spu_runcntl_RW;
3095 unsigned long dump_addr;
3099 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3101 static struct spu_info spu_info[XMON_NUM_SPUS];
3103 void xmon_register_spus(struct list_head *list)
3107 list_for_each_entry(spu, list, full_list) {
3108 if (spu->number >= XMON_NUM_SPUS) {
3113 spu_info[spu->number].spu = spu;
3114 spu_info[spu->number].stopped_ok = 0;
3115 spu_info[spu->number].dump_addr = (unsigned long)
3116 spu_info[spu->number].spu->local_store;
3120 static void stop_spus(void)
3126 for (i = 0; i < XMON_NUM_SPUS; i++) {
3127 if (!spu_info[i].spu)
3130 if (setjmp(bus_error_jmp) == 0) {
3131 catch_memory_errors = 1;
3134 spu = spu_info[i].spu;
3136 spu_info[i].saved_spu_runcntl_RW =
3137 in_be32(&spu->problem->spu_runcntl_RW);
3139 tmp = spu_mfc_sr1_get(spu);
3140 spu_info[i].saved_mfc_sr1_RW = tmp;
3142 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3143 spu_mfc_sr1_set(spu, tmp);
3148 spu_info[i].stopped_ok = 1;
3150 printf("Stopped spu %.2d (was %s)\n", i,
3151 spu_info[i].saved_spu_runcntl_RW ?
3152 "running" : "stopped");
3154 catch_memory_errors = 0;
3155 printf("*** Error stopping spu %.2d\n", i);
3157 catch_memory_errors = 0;
3161 static void restart_spus(void)
3166 for (i = 0; i < XMON_NUM_SPUS; i++) {
3167 if (!spu_info[i].spu)
3170 if (!spu_info[i].stopped_ok) {
3171 printf("*** Error, spu %d was not successfully stopped"
3172 ", not restarting\n", i);
3176 if (setjmp(bus_error_jmp) == 0) {
3177 catch_memory_errors = 1;
3180 spu = spu_info[i].spu;
3181 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3182 out_be32(&spu->problem->spu_runcntl_RW,
3183 spu_info[i].saved_spu_runcntl_RW);
3188 printf("Restarted spu %.2d\n", i);
3190 catch_memory_errors = 0;
3191 printf("*** Error restarting spu %.2d\n", i);
3193 catch_memory_errors = 0;
3197 #define DUMP_WIDTH 23
3198 #define DUMP_VALUE(format, field, value) \
3200 if (setjmp(bus_error_jmp) == 0) { \
3201 catch_memory_errors = 1; \
3203 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3208 catch_memory_errors = 0; \
3209 printf(" %-*s = *** Error reading field.\n", \
3210 DUMP_WIDTH, #field); \
3212 catch_memory_errors = 0; \
3215 #define DUMP_FIELD(obj, format, field) \
3216 DUMP_VALUE(format, field, obj->field)
3218 static void dump_spu_fields(struct spu *spu)
3220 printf("Dumping spu fields at address %p:\n", spu);
3222 DUMP_FIELD(spu, "0x%x", number);
3223 DUMP_FIELD(spu, "%s", name);
3224 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3225 DUMP_FIELD(spu, "0x%p", local_store);
3226 DUMP_FIELD(spu, "0x%lx", ls_size);
3227 DUMP_FIELD(spu, "0x%x", node);
3228 DUMP_FIELD(spu, "0x%lx", flags);
3229 DUMP_FIELD(spu, "%d", class_0_pending);
3230 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3231 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3232 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3233 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3234 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3235 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3236 DUMP_FIELD(spu, "0x%x", slb_replace);
3237 DUMP_FIELD(spu, "%d", pid);
3238 DUMP_FIELD(spu, "0x%p", mm);
3239 DUMP_FIELD(spu, "0x%p", ctx);
3240 DUMP_FIELD(spu, "0x%p", rq);
3241 DUMP_FIELD(spu, "0x%p", timestamp);
3242 DUMP_FIELD(spu, "0x%lx", problem_phys);
3243 DUMP_FIELD(spu, "0x%p", problem);
3244 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3245 in_be32(&spu->problem->spu_runcntl_RW));
3246 DUMP_VALUE("0x%x", problem->spu_status_R,
3247 in_be32(&spu->problem->spu_status_R));
3248 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3249 in_be32(&spu->problem->spu_npc_RW));
3250 DUMP_FIELD(spu, "0x%p", priv2);
3251 DUMP_FIELD(spu, "0x%p", pdata);
3255 spu_inst_dump(unsigned long adr, long count, int praddr)
3257 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3260 static void dump_spu_ls(unsigned long num, int subcmd)
3262 unsigned long offset, addr, ls_addr;
3264 if (setjmp(bus_error_jmp) == 0) {
3265 catch_memory_errors = 1;
3267 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3271 catch_memory_errors = 0;
3272 printf("*** Error: accessing spu info for spu %d\n", num);
3275 catch_memory_errors = 0;
3277 if (scanhex(&offset))
3278 addr = ls_addr + offset;
3280 addr = spu_info[num].dump_addr;
3282 if (addr >= ls_addr + LS_SIZE) {
3283 printf("*** Error: address outside of local store\n");
3289 addr += spu_inst_dump(addr, 16, 1);
3299 spu_info[num].dump_addr = addr;
3302 static int do_spu_cmd(void)
3304 static unsigned long num = 0;
3305 int cmd, subcmd = 0;
3317 if (isxdigit(subcmd) || subcmd == '\n')
3321 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3322 printf("*** Error: invalid spu number\n");
3328 dump_spu_fields(spu_info[num].spu);
3331 dump_spu_ls(num, subcmd);
3342 #else /* ! CONFIG_SPU_BASE */
3343 static int do_spu_cmd(void)