of: MSI: Simplify irqdomain lookup
[linux/fpc-iii.git] / arch / powerpc / xmon / xmon.c
blob786bf01691c9802420e7e6f40d4b6415cd18cfb5
1 /*
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>
16 #include <linux/mm.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>
32 #include <asm/prom.h>
33 #include <asm/machdep.h>
34 #include <asm/xmon.h>
35 #include <asm/processor.h>
36 #include <asm/pgtable.h>
37 #include <asm/mmu.h>
38 #include <asm/mmu_context.h>
39 #include <asm/cputable.h>
40 #include <asm/rtas.h>
41 #include <asm/sstep.h>
42 #include <asm/irq_regs.h>
43 #include <asm/spu.h>
44 #include <asm/spu_priv1.h>
45 #include <asm/setjmp.h>
46 #include <asm/reg.h>
47 #include <asm/debug.h>
48 #include <asm/hw_breakpoint.h>
50 #ifdef CONFIG_PPC64
51 #include <asm/hvcall.h>
52 #include <asm/paca.h>
53 #endif
55 #if defined(CONFIG_PPC_SPLPAR)
56 #include <asm/plpar_wrappers.h>
57 #else
58 static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
59 #endif
61 #include "nonstdio.h"
62 #include "dis-asm.h"
64 #ifdef CONFIG_SMP
65 static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
66 static unsigned long xmon_taken = 1;
67 static int xmon_owner;
68 static int xmon_gate;
69 #else
70 #define xmon_owner 0
71 #endif /* CONFIG_SMP */
73 static unsigned long in_xmon __read_mostly = 0;
75 static unsigned long adrs;
76 static int size = 1;
77 #define MAX_DUMP (128 * 1024)
78 static unsigned long ndump = 64;
79 static unsigned long nidump = 16;
80 static unsigned long ncsum = 4096;
81 static int termch;
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 */
89 struct bpt {
90 unsigned long address;
91 unsigned int instr[2];
92 atomic_t ref_count;
93 int enabled;
94 unsigned long pad;
97 /* Bits in bpt.enabled */
98 #define BP_CIABR 1
99 #define BP_TRAP 2
100 #define BP_DABR 4
102 #define NBPTS 256
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)
110 /* Prototypes */
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);
129 int skipbl(void);
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,
156 unsigned long pc);
157 static void xmon_print_symbol(unsigned long address, const char *mid,
158 const char *after);
159 static const char *getvecname(unsigned long vec);
161 static int do_spu_cmd(void);
163 #ifdef CONFIG_44x
164 static void dump_tlb_44x(void);
165 #endif
166 #ifdef CONFIG_PPC_BOOK3E
167 static void dump_tlb_book3e(void);
168 #endif
170 static int xmon_no_auto_backtrace;
172 extern void xmon_enter(void);
173 extern void xmon_leave(void);
175 #ifdef CONFIG_PPC64
176 #define REG "%.16lx"
177 #else
178 #define REG "%.8lx"
179 #endif
181 #ifdef __LITTLE_ENDIAN__
182 #define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
183 #else
184 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
185 #endif
187 static char *help_string = "\
188 Commands:\n\
189 b show breakpoints\n\
190 bd set data breakpoint\n\
191 bi set instruction breakpoint\n\
192 bc clear breakpoint\n"
193 #ifdef CONFIG_SMP
195 c print cpus stopped in xmon\n\
196 c# try to switch to cpu number h (in hex)\n"
197 #endif
199 C checksum\n\
200 d dump bytes\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"
205 #ifdef CONFIG_PPC64
207 dp[#] dump paca for current cpu, or cpu #\n\
208 dpa dump paca for all possible cpus\n"
209 #endif
211 dr dump stream of raw bytes\n\
212 e print exception information\n\
213 f flush cache\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\
224 r print registers\n\
225 s single step\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"
232 #endif
233 " S print special registers\n\
234 t print backtrace\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)
242 " u dump TLB\n"
243 #endif
244 " ? help\n"
245 " # n limit output to n lines per page (for dp, dpa, dl)\n"
246 " zr reboot\n\
247 zh halt\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))
284 return;
286 if (cpu_has_feature(CPU_FTR_HVMODE)) {
287 mtspr(SPRN_CIABR, ciabr);
288 return;
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)
302 addr &= ~CIABR_PRIV;
304 if (cpu_has_feature(CPU_FTR_HVMODE))
305 addr |= CIABR_PRIV_HYPER;
306 else
307 addr |= CIABR_PRIV_SUPER;
308 write_ciabr(addr);
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)
333 return;
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);
339 args.args[1] = 0;
340 args.args[2] = 0;
341 enter_rtas(__pa(&args));
342 #endif /* CONFIG_PPC_PSERIES */
345 #ifdef CONFIG_SMP
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;
352 long timeout;
354 if (xmon_speaker == me)
355 return;
357 for (;;) {
358 last_speaker = cmpxchg(&xmon_speaker, 0, me);
359 if (last_speaker == 0)
360 return;
363 * Wait a full second for the lock, we might be on a slow
364 * console, but check every 100us.
366 timeout = 10000;
367 while (xmon_speaker == last_speaker) {
368 if (--timeout > 0) {
369 udelay(100);
370 continue;
373 /* hostile takeover */
374 prev = cmpxchg(&xmon_speaker, last_speaker, me);
375 if (prev == last_speaker)
376 return;
377 break;
382 static void release_output_lock(void)
384 xmon_speaker = 0;
387 int cpus_are_in_xmon(void)
389 return !cpumask_empty(&cpus_in_xmon);
391 #endif
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 */
397 return 0;
398 #else
399 return ((regs->msr & MSR_RI) == 0);
400 #endif
403 static int xmon_core(struct pt_regs *regs, int fromipi)
405 int cmd = 0;
406 struct bpt *bp;
407 long recurse_jmp[JMP_BUF_LEN];
408 unsigned long offset;
409 unsigned long flags;
410 #ifdef CONFIG_SMP
411 int cpu;
412 int secondary;
413 unsigned long timeout;
414 #endif
416 local_irq_save(flags);
417 hard_irq_disable();
419 bp = in_breakpoint_table(regs->nip, &offset);
420 if (bp != NULL) {
421 regs->nip = bp->address + offset;
422 atomic_dec(&bp->ref_count);
425 remove_cpu_bpts();
427 #ifdef CONFIG_SMP
428 cpu = smp_processor_id();
429 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
430 get_output_lock();
431 excprint(regs);
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) {
441 get_output_lock();
442 printf("xmon: WARNING: bad recursive fault "
443 "on cpu 0x%x\n", cpu);
444 release_output_lock();
445 goto waiting;
447 secondary = !(xmon_taken && cpu == xmon_owner);
448 goto cmdloop;
451 xmon_fault_jmp[cpu] = recurse_jmp;
453 bp = NULL;
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))
457 fromipi = 0;
459 if (!fromipi) {
460 get_output_lock();
461 excprint(regs);
462 if (bp) {
463 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
464 cpu, BP_NUM(bp));
465 xmon_print_symbol(regs->nip, " ", ")\n");
467 if (unrecoverable_excp(regs))
468 printf("WARNING: exception is not recoverable, "
469 "can't continue\n");
470 release_output_lock();
473 cpumask_set_cpu(cpu, &cpus_in_xmon);
475 waiting:
476 secondary = 1;
477 while (secondary && !xmon_gate) {
478 if (in_xmon == 0) {
479 if (fromipi)
480 goto leave;
481 secondary = test_and_set_bit(0, &in_xmon);
483 barrier();
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();
491 xmon_owner = cpu;
492 mb();
493 if (ncpus > 1) {
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)
498 break;
499 barrier();
502 remove_bpts();
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");
508 mb();
509 xmon_gate = 1;
510 barrier();
513 cmdloop:
514 while (in_xmon) {
515 if (secondary) {
516 if (cpu == xmon_owner) {
517 if (!test_and_set_bit(0, &xmon_taken)) {
518 secondary = 0;
519 continue;
521 /* missed it */
522 while (cpu == xmon_owner)
523 barrier();
525 barrier();
526 } else {
527 cmd = cmds(regs);
528 if (cmd != 0) {
529 /* exiting xmon */
530 insert_bpts();
531 xmon_gate = 0;
532 wmb();
533 in_xmon = 0;
534 break;
536 /* have switched to some other cpu */
537 secondary = 1;
540 leave:
541 cpumask_clear_cpu(cpu, &cpus_in_xmon);
542 xmon_fault_jmp[cpu] = NULL;
543 #else
544 /* UP is simple... */
545 if (in_xmon) {
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;
552 in_xmon = 1;
554 excprint(regs);
555 bp = at_breakpoint(regs->nip);
556 if (bp) {
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, "
562 "can't continue\n");
563 remove_bpts();
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");
571 cmd = cmds(regs);
573 insert_bpts();
574 in_xmon = 0;
575 #endif
577 #ifdef CONFIG_BOOKE
578 if (regs->msr & MSR_DE) {
579 bp = at_breakpoint(regs->nip);
580 if (bp != NULL) {
581 regs->nip = (unsigned long) &bp->instr[0];
582 atomic_inc(&bp->ref_count);
585 #else
586 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
587 bp = at_breakpoint(regs->nip);
588 if (bp != NULL) {
589 int stepped = emulate_step(regs, bp->instr[0]);
590 if (stepped == 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"));
599 #endif
600 insert_cpu_bpts();
602 touch_nmi_watchdog();
603 local_irq_restore(flags);
605 return cmd != 'X' && cmd != EOF;
608 int xmon(struct pt_regs *excp)
610 struct pt_regs regs;
612 if (excp == NULL) {
613 ppc_save_regs(&regs);
614 excp = &regs;
617 return xmon_core(excp, 0);
619 EXPORT_SYMBOL(xmon);
621 irqreturn_t xmon_irq(int irq, void *d)
623 unsigned long flags;
624 local_irq_save(flags);
625 printf("Keyboard interrupt\n");
626 xmon(get_irq_regs());
627 local_irq_restore(flags);
628 return IRQ_HANDLED;
631 static int xmon_bpt(struct pt_regs *regs)
633 struct bpt *bp;
634 unsigned long offset;
636 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
637 return 0;
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);
644 return 1;
647 /* Are we at a breakpoint? */
648 bp = at_breakpoint(regs->nip);
649 if (!bp)
650 return 0;
652 xmon_core(regs, 0);
654 return 1;
657 static int xmon_sstep(struct pt_regs *regs)
659 if (user_mode(regs))
660 return 0;
661 xmon_core(regs, 0);
662 return 1;
665 static int xmon_break_match(struct pt_regs *regs)
667 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
668 return 0;
669 if (dabr.enabled == 0)
670 return 0;
671 xmon_core(regs, 0);
672 return 1;
675 static int xmon_iabr_match(struct pt_regs *regs)
677 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
678 return 0;
679 if (iabr == NULL)
680 return 0;
681 xmon_core(regs, 0);
682 return 1;
685 static int xmon_ipi(struct pt_regs *regs)
687 #ifdef CONFIG_SMP
688 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
689 xmon_core(regs, 1);
690 #endif
691 return 0;
694 static int xmon_fault_handler(struct pt_regs *regs)
696 struct bpt *bp;
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);
704 if (bp != NULL) {
705 regs->nip = bp->address + offset;
706 atomic_dec(&bp->ref_count);
710 return 0;
713 static struct bpt *at_breakpoint(unsigned long pc)
715 int i;
716 struct bpt *bp;
718 bp = bpts;
719 for (i = 0; i < NBPTS; ++i, ++bp)
720 if (bp->enabled && pc == bp->address)
721 return bp;
722 return NULL;
725 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
727 unsigned long off;
729 off = nip - (unsigned long) bpts;
730 if (off >= sizeof(bpts))
731 return NULL;
732 off %= sizeof(struct bpt);
733 if (off != offsetof(struct bpt, instr[0])
734 && off != offsetof(struct bpt, instr[1]))
735 return NULL;
736 *offp = off - offsetof(struct bpt, instr[0]);
737 return (struct bpt *) (nip - off);
740 static struct bpt *new_breakpoint(unsigned long a)
742 struct bpt *bp;
744 a &= ~3UL;
745 bp = at_breakpoint(a);
746 if (bp)
747 return bp;
749 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
750 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
751 bp->address = a;
752 bp->instr[1] = bpinstr;
753 store_inst(&bp->instr[1]);
754 return bp;
758 printf("Sorry, no free breakpoints. Please clear one first.\n");
759 return NULL;
762 static void insert_bpts(void)
764 int i;
765 struct bpt *bp;
767 bp = bpts;
768 for (i = 0; i < NBPTS; ++i, ++bp) {
769 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
770 continue;
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);
774 bp->enabled = 0;
775 continue;
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);
780 bp->enabled = 0;
781 continue;
783 store_inst(&bp->instr[0]);
784 if (bp->enabled & BP_CIABR)
785 continue;
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;
790 continue;
792 store_inst((void *)bp->address);
796 static void insert_cpu_bpts(void)
798 struct arch_hw_breakpoint brk;
800 if (dabr.enabled) {
801 brk.address = dabr.address;
802 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
803 brk.len = 8;
804 __set_breakpoint(&brk);
807 if (iabr)
808 set_ciabr(iabr->address);
811 static void remove_bpts(void)
813 int i;
814 struct bpt *bp;
815 unsigned instr;
817 bp = bpts;
818 for (i = 0; i < NBPTS; ++i, ++bp) {
819 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
820 continue;
821 if (mread(bp->address, &instr, 4) == 4
822 && instr == bpinstr
823 && mwrite(bp->address, &bp->instr, 4) != 4)
824 printf("Couldn't remove breakpoint at %lx\n",
825 bp->address);
826 else
827 store_inst((void *)bp->address);
831 static void remove_cpu_bpts(void)
833 hw_breakpoint_disable();
834 write_ciabr(0);
837 static void set_lpp_cmd(void)
839 unsigned long lpp;
841 if (!scanhex(&lpp)) {
842 printf("Invalid number.\n");
843 lpp = 0;
845 xmon_set_pagination_lpp(lpp);
847 /* Command interpreting routine */
848 static char *last_cmd;
850 static int
851 cmds(struct pt_regs *excp)
853 int cmd = 0;
855 last_cmd = NULL;
856 xmon_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);
863 for(;;) {
864 #ifdef CONFIG_SMP
865 printf("%x:", smp_processor_id());
866 #endif /* CONFIG_SMP */
867 printf("mon> ");
868 flush_input();
869 termch = 0;
870 cmd = skipbl();
871 if( cmd == '\n' ) {
872 if (last_cmd == NULL)
873 continue;
874 take_input(last_cmd);
875 last_cmd = NULL;
876 cmd = inchar();
878 switch (cmd) {
879 case 'm':
880 cmd = inchar();
881 switch (cmd) {
882 case 'm':
883 case 's':
884 case 'd':
885 memops(cmd);
886 break;
887 case 'l':
888 memlocate();
889 break;
890 case 'z':
891 memzcan();
892 break;
893 case 'i':
894 show_mem(0);
895 break;
896 default:
897 termch = cmd;
898 memex();
900 break;
901 case 'd':
902 dump();
903 break;
904 case 'l':
905 symbol_lookup();
906 break;
907 case 'r':
908 prregs(excp); /* print regs */
909 break;
910 case 'e':
911 excprint(excp);
912 break;
913 case 'S':
914 super_regs();
915 break;
916 case 't':
917 backtrace(excp);
918 break;
919 case 'f':
920 cacheflush();
921 break;
922 case 's':
923 if (do_spu_cmd() == 0)
924 break;
925 if (do_step(excp))
926 return cmd;
927 break;
928 case 'x':
929 case 'X':
930 return cmd;
931 case EOF:
932 printf(" <no input ...>\n");
933 mdelay(2000);
934 return cmd;
935 case '?':
936 xmon_puts(help_string);
937 break;
938 case '#':
939 set_lpp_cmd();
940 break;
941 case 'b':
942 bpt_cmds();
943 break;
944 case 'C':
945 csum();
946 break;
947 case 'c':
948 if (cpu_cmd())
949 return 0;
950 break;
951 case 'z':
952 bootcmds();
953 break;
954 case 'p':
955 proccall();
956 break;
957 #ifdef CONFIG_PPC_STD_MMU
958 case 'u':
959 dump_segments();
960 break;
961 #elif defined(CONFIG_44x)
962 case 'u':
963 dump_tlb_44x();
964 break;
965 #elif defined(CONFIG_PPC_BOOK3E)
966 case 'u':
967 dump_tlb_book3e();
968 break;
969 #endif
970 default:
971 printf("Unrecognized command: ");
972 do {
973 if (' ' < cmd && cmd <= '~')
974 putchar(cmd);
975 else
976 printf("\\x%x", cmd);
977 cmd = inchar();
978 } while (cmd != '\n');
979 printf(" (type ? for help)\n");
980 break;
985 #ifdef CONFIG_BOOKE
986 static int do_step(struct pt_regs *regs)
988 regs->msr |= MSR_DE;
989 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
990 return 1;
992 #else
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)
999 unsigned int instr;
1000 int stepped;
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);
1006 if (stepped < 0) {
1007 printf("Couldn't single-step %s instruction\n",
1008 (IS_RFID(instr)? "rfid": "mtmsrd"));
1009 return 0;
1011 if (stepped > 0) {
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);
1016 return 0;
1020 regs->msr |= MSR_SE;
1021 return 1;
1023 #endif
1025 static void bootcmds(void)
1027 int cmd;
1029 cmd = inchar();
1030 if (cmd == 'r')
1031 ppc_md.restart(NULL);
1032 else if (cmd == 'h')
1033 ppc_md.halt();
1034 else if (cmd == 'p')
1035 if (pm_power_off)
1036 pm_power_off();
1039 static int cpu_cmd(void)
1041 #ifdef CONFIG_SMP
1042 unsigned long cpu, first_cpu, last_cpu;
1043 int timeout;
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) {
1052 last_cpu = cpu;
1053 } else {
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);
1063 printf("\n");
1064 return 0;
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);
1069 return 0;
1071 xmon_taken = 0;
1072 mb();
1073 xmon_owner = cpu;
1074 timeout = 10000000;
1075 while (!xmon_taken) {
1076 if (--timeout == 0) {
1077 if (test_and_set_bit(0, &xmon_taken))
1078 break;
1079 /* take control back */
1080 mb();
1081 xmon_owner = smp_processor_id();
1082 printf("cpu 0x%x didn't take control\n", cpu);
1083 return 0;
1085 barrier();
1087 return 1;
1088 #else
1089 return 0;
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])
1130 static void
1131 csum(void)
1133 unsigned int i;
1134 unsigned short fcs;
1135 unsigned char v;
1137 if (!scanhex(&adrs))
1138 return;
1139 if (!scanhex(&ncsum))
1140 return;
1141 fcs = 0xffff;
1142 for (i = 0; i < ncsum; ++i) {
1143 if (mread(adrs+i, &v, 1) == 0) {
1144 printf("csum stopped at "REG"\n", adrs+i);
1145 break;
1147 fcs = FCS(fcs, v);
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)
1157 unsigned int instr;
1159 addr &= ~3;
1160 if (!is_kernel_addr(addr)) {
1161 printf("Breakpoints may only be placed at kernel addresses\n");
1162 return 0;
1164 if (!mread(addr, &instr, sizeof(instr))) {
1165 printf("Can't read instruction at address %lx\n", addr);
1166 return 0;
1168 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1169 printf("Breakpoints may not be placed on mtmsrd or rfid "
1170 "instructions\n");
1171 return 0;
1173 return 1;
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"
1186 static void
1187 bpt_cmds(void)
1189 int cmd;
1190 unsigned long a;
1191 int mode, i;
1192 struct bpt *bp;
1193 const char badaddr[] = "Only kernel addresses are permitted "
1194 "for breakpoints\n";
1196 cmd = inchar();
1197 switch (cmd) {
1198 #ifndef CONFIG_8xx
1199 case 'd': /* bd - hardware data breakpoint */
1200 mode = 7;
1201 cmd = inchar();
1202 if (cmd == 'r')
1203 mode = 5;
1204 else if (cmd == 'w')
1205 mode = 6;
1206 else
1207 termch = cmd;
1208 dabr.address = 0;
1209 dabr.enabled = 0;
1210 if (scanhex(&dabr.address)) {
1211 if (!is_kernel_addr(dabr.address)) {
1212 printf(badaddr);
1213 break;
1215 dabr.address &= ~HW_BRK_TYPE_DABR;
1216 dabr.enabled = mode | BP_DABR;
1218 break;
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");
1224 break;
1226 if (iabr) {
1227 iabr->enabled &= ~BP_CIABR;
1228 iabr = NULL;
1230 if (!scanhex(&a))
1231 break;
1232 if (!check_bp_loc(a))
1233 break;
1234 bp = new_breakpoint(a);
1235 if (bp != NULL) {
1236 bp->enabled |= BP_CIABR;
1237 iabr = bp;
1239 break;
1240 #endif
1242 case 'c':
1243 if (!scanhex(&a)) {
1244 /* clear all breakpoints */
1245 for (i = 0; i < NBPTS; ++i)
1246 bpts[i].enabled = 0;
1247 iabr = NULL;
1248 dabr.enabled = 0;
1249 printf("All breakpoints cleared\n");
1250 break;
1253 if (a <= NBPTS && a >= 1) {
1254 /* assume a breakpoint number */
1255 bp = &bpts[a-1]; /* bp nums are 1 based */
1256 } else {
1257 /* assume a breakpoint address */
1258 bp = at_breakpoint(a);
1259 if (bp == NULL) {
1260 printf("No breakpoint at %lx\n", a);
1261 break;
1265 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1266 xmon_print_symbol(bp->address, " ", ")\n");
1267 bp->enabled = 0;
1268 break;
1270 default:
1271 termch = cmd;
1272 cmd = skipbl();
1273 if (cmd == '?') {
1274 printf(breakpoint_help_string);
1275 break;
1277 termch = cmd;
1278 if (!scanhex(&a)) {
1279 /* print all breakpoints */
1280 printf(" type address\n");
1281 if (dabr.enabled) {
1282 printf(" data "REG" [", dabr.address);
1283 if (dabr.enabled & 1)
1284 printf("r");
1285 if (dabr.enabled & 2)
1286 printf("w");
1287 printf("]\n");
1289 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1290 if (!bp->enabled)
1291 continue;
1292 printf("%2x %s ", BP_NUM(bp),
1293 (bp->enabled & BP_CIABR) ? "inst": "trap");
1294 xmon_print_symbol(bp->address, " ", "\n");
1296 break;
1299 if (!check_bp_loc(a))
1300 break;
1301 bp = new_breakpoint(a);
1302 if (bp != NULL)
1303 bp->enabled |= BP_TRAP;
1304 break;
1308 /* Very cheap human name for vector lookup. */
1309 static
1310 const char *getvecname(unsigned long vec)
1312 char *ret;
1314 switch (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;
1338 default: ret = "";
1340 return ret;
1343 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1344 unsigned long *endp)
1346 unsigned long size, offset;
1347 const char *name;
1349 *startp = *endp = 0;
1350 if (pc == 0)
1351 return;
1352 if (setjmp(bus_error_jmp) == 0) {
1353 catch_memory_errors = 1;
1354 sync();
1355 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1356 if (name != NULL) {
1357 *startp = pc - offset;
1358 *endp = pc - offset + size;
1360 sync();
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,
1369 unsigned long pc)
1371 int max_to_print = 64;
1372 unsigned long ip;
1373 unsigned long newsp;
1374 unsigned long marker;
1375 struct pt_regs regs;
1377 while (max_to_print--) {
1378 if (sp < PAGE_OFFSET) {
1379 if (sp != 0)
1380 printf("SP (%lx) is in userspace\n", sp);
1381 break;
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);
1387 break;
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;
1398 int printip = 1;
1400 get_function_bounds(pc, &fnstart, &fnend);
1401 nextip = 0;
1402 if (newsp > sp)
1403 mread(newsp + LRSAVE_OFFSET, &nextip,
1404 sizeof(unsigned long));
1405 if (lr == ip) {
1406 if (lr < PAGE_OFFSET
1407 || (fnstart <= lr && lr < fnend))
1408 printip = 0;
1409 } else if (lr == nextip) {
1410 printip = 0;
1411 } else if (lr >= PAGE_OFFSET
1412 && !(fnstart <= lr && lr < fnend)) {
1413 printf("[link register ] ");
1414 xmon_print_symbol(lr, " ", "\n");
1416 if (printip) {
1417 printf("["REG"] ", sp);
1418 xmon_print_symbol(ip, " ", " (unreliable)\n");
1420 pc = lr = 0;
1422 } else {
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, &regs, sizeof(regs))
1432 != sizeof(regs)) {
1433 printf("Couldn't read registers at %lx\n",
1434 sp + STACK_FRAME_OVERHEAD);
1435 break;
1437 printf("--- Exception: %lx %s at ", regs.trap,
1438 getvecname(TRAP(&regs)));
1439 pc = regs.nip;
1440 lr = regs.link;
1441 xmon_print_symbol(pc, " ", "\n");
1444 if (newsp == 0)
1445 break;
1447 sp = newsp;
1451 static void backtrace(struct pt_regs *excp)
1453 unsigned long sp;
1455 if (scanhex(&sp))
1456 xmon_show_stack(sp, 0, 0);
1457 else
1458 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1459 scannl();
1462 static void print_bug_trap(struct pt_regs *regs)
1464 #ifdef CONFIG_BUG
1465 const struct bug_entry *bug;
1466 unsigned long addr;
1468 if (regs->msr & MSR_PR)
1469 return; /* not in kernel */
1470 addr = regs->nip; /* address of trap instruction */
1471 if (addr < PAGE_OFFSET)
1472 return;
1473 bug = find_bug(regs->nip);
1474 if (bug == NULL)
1475 return;
1476 if (is_warning_bug(bug))
1477 return;
1479 #ifdef CONFIG_DEBUG_BUGVERBOSE
1480 printf("kernel BUG at %s:%u!\n",
1481 bug->file, bug->line);
1482 #else
1483 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1484 #endif
1485 #endif /* CONFIG_BUG */
1488 static void excprint(struct pt_regs *fp)
1490 unsigned long trap;
1492 #ifdef CONFIG_SMP
1493 printf("cpu 0x%x: ", smp_processor_id());
1494 #endif /* CONFIG_SMP */
1496 trap = TRAP(fp);
1497 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1498 printf(" pc: ");
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);
1509 if (trap != 0x380)
1510 printf(" dsisr: %lx\n", fp->dsisr);
1513 printf(" current = 0x%lx\n", current);
1514 #ifdef CONFIG_PPC64
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);
1517 #endif
1518 if (current) {
1519 printf(" pid = %ld, comm = %s\n",
1520 current->pid, current->comm);
1523 if (trap == 0x700)
1524 print_bug_trap(fp);
1527 static void prregs(struct pt_regs *fp)
1529 int n, trap;
1530 unsigned long base;
1531 struct pt_regs regs;
1533 if (scanhex(&base)) {
1534 if (setjmp(bus_error_jmp) == 0) {
1535 catch_memory_errors = 1;
1536 sync();
1537 regs = *(struct pt_regs *)base;
1538 sync();
1539 __delay(200);
1540 } else {
1541 catch_memory_errors = 0;
1542 printf("*** Error reading registers from "REG"\n",
1543 base);
1544 return;
1546 catch_memory_errors = 0;
1547 fp = &regs;
1550 #ifdef CONFIG_PPC64
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]);
1555 } else {
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]);
1560 #else
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)) {
1565 printf("\n");
1566 break;
1569 #endif
1570 printf("pc = ");
1571 xmon_print_symbol(fp->nip, " ", "\n");
1572 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1573 printf("cfar= ");
1574 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1576 printf("lr = ");
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);
1581 trap = TRAP(fp);
1582 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1583 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1586 static void cacheflush(void)
1588 int cmd;
1589 unsigned long nflush;
1591 cmd = inchar();
1592 if (cmd != 'i')
1593 termch = cmd;
1594 scanhex((void *)&adrs);
1595 if (termch != '\n')
1596 termch = 0;
1597 nflush = 1;
1598 scanhex(&nflush);
1599 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1600 if (setjmp(bus_error_jmp) == 0) {
1601 catch_memory_errors = 1;
1602 sync();
1604 if (cmd != 'i') {
1605 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1606 cflush((void *) adrs);
1607 } else {
1608 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1609 cinval((void *) adrs);
1611 sync();
1612 /* wait a little while to see if we get a machine check */
1613 __delay(200);
1615 catch_memory_errors = 0;
1618 static unsigned long
1619 read_spr(int n)
1621 unsigned int instrs[2];
1622 unsigned long (*code)(void);
1623 unsigned long ret = -1UL;
1624 #ifdef CONFIG_PPC64
1625 unsigned long opd[3];
1627 opd[0] = (unsigned long)instrs;
1628 opd[1] = 0;
1629 opd[2] = 0;
1630 code = (unsigned long (*)(void)) opd;
1631 #else
1632 code = (unsigned long (*)(void)) instrs;
1633 #endif
1635 /* mfspr r3,n; blr */
1636 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1637 instrs[1] = 0x4e800020;
1638 store_inst(instrs);
1639 store_inst(instrs+1);
1641 if (setjmp(bus_error_jmp) == 0) {
1642 catch_memory_errors = 1;
1643 sync();
1645 ret = code();
1647 sync();
1648 /* wait a little while to see if we get a machine check */
1649 __delay(200);
1650 n = size;
1653 return ret;
1656 static void
1657 write_spr(int n, unsigned long val)
1659 unsigned int instrs[2];
1660 unsigned long (*code)(unsigned long);
1661 #ifdef CONFIG_PPC64
1662 unsigned long opd[3];
1664 opd[0] = (unsigned long)instrs;
1665 opd[1] = 0;
1666 opd[2] = 0;
1667 code = (unsigned long (*)(unsigned long)) opd;
1668 #else
1669 code = (unsigned long (*)(unsigned long)) instrs;
1670 #endif
1672 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1673 instrs[1] = 0x4e800020;
1674 store_inst(instrs);
1675 store_inst(instrs+1);
1677 if (setjmp(bus_error_jmp) == 0) {
1678 catch_memory_errors = 1;
1679 sync();
1681 code(val);
1683 sync();
1684 /* wait a little while to see if we get a machine check */
1685 __delay(200);
1686 n = size;
1690 static unsigned long regno;
1691 extern char exc_prolog;
1692 extern char dec_exc;
1694 static void super_regs(void)
1696 int cmd;
1697 unsigned long val;
1699 cmd = skipbl();
1700 if (cmd == '\n') {
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));
1714 return;
1717 scanhex(&regno);
1718 switch (cmd) {
1719 case 'w':
1720 val = read_spr(regno);
1721 scanhex(&val);
1722 write_spr(regno, val);
1723 /* fall through */
1724 case 'r':
1725 printf("spr %lx = %lx\n", regno, read_spr(regno));
1726 break;
1728 scannl();
1732 * Stuff for reading and writing memory safely
1734 static int
1735 mread(unsigned long adrs, void *buf, int size)
1737 volatile int n;
1738 char *p, *q;
1740 n = 0;
1741 if (setjmp(bus_error_jmp) == 0) {
1742 catch_memory_errors = 1;
1743 sync();
1744 p = (char *)adrs;
1745 q = (char *)buf;
1746 switch (size) {
1747 case 2:
1748 *(u16 *)q = *(u16 *)p;
1749 break;
1750 case 4:
1751 *(u32 *)q = *(u32 *)p;
1752 break;
1753 case 8:
1754 *(u64 *)q = *(u64 *)p;
1755 break;
1756 default:
1757 for( ; n < size; ++n) {
1758 *q++ = *p++;
1759 sync();
1762 sync();
1763 /* wait a little while to see if we get a machine check */
1764 __delay(200);
1765 n = size;
1767 catch_memory_errors = 0;
1768 return n;
1771 static int
1772 mwrite(unsigned long adrs, void *buf, int size)
1774 volatile int n;
1775 char *p, *q;
1777 n = 0;
1778 if (setjmp(bus_error_jmp) == 0) {
1779 catch_memory_errors = 1;
1780 sync();
1781 p = (char *) adrs;
1782 q = (char *) buf;
1783 switch (size) {
1784 case 2:
1785 *(u16 *)p = *(u16 *)q;
1786 break;
1787 case 4:
1788 *(u32 *)p = *(u32 *)q;
1789 break;
1790 case 8:
1791 *(u64 *)p = *(u64 *)q;
1792 break;
1793 default:
1794 for ( ; n < size; ++n) {
1795 *p++ = *q++;
1796 sync();
1799 sync();
1800 /* wait a little while to see if we get a machine check */
1801 __delay(200);
1802 n = size;
1803 } else {
1804 printf("*** Error writing address "REG"\n", adrs + n);
1806 catch_memory_errors = 0;
1807 return n;
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)) {
1818 case 0x200:
1819 fault_type = 0;
1820 break;
1821 case 0x300:
1822 case 0x380:
1823 fault_type = 1;
1824 break;
1825 default:
1826 fault_type = 2;
1829 longjmp(bus_error_jmp, 1);
1831 return 0;
1834 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1836 static void
1837 byterev(unsigned char *val, int size)
1839 int t;
1841 switch (size) {
1842 case 2:
1843 SWAP(val[0], val[1], t);
1844 break;
1845 case 4:
1846 SWAP(val[0], val[3], t);
1847 SWAP(val[1], val[2], t);
1848 break;
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);
1854 break;
1858 static int brev;
1859 static int mnoread;
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"
1898 static void
1899 memex(void)
1901 int cmd, inc, i, nslash;
1902 unsigned long n;
1903 unsigned char val[16];
1905 scanhex((void *)&adrs);
1906 cmd = skipbl();
1907 if (cmd == '?') {
1908 printf(memex_help_string);
1909 return;
1910 } else {
1911 termch = cmd;
1913 last_cmd = "m\n";
1914 while ((cmd = skipbl()) != '\n') {
1915 switch( cmd ){
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;
1925 if( size <= 0 )
1926 size = 1;
1927 else if( size > 8 )
1928 size = 8;
1929 for(;;){
1930 if (!mnoread)
1931 n = mread(adrs, val, size);
1932 printf(REG"%c", adrs, brev? 'r': ' ');
1933 if (!mnoread) {
1934 if (brev)
1935 byterev(val, size);
1936 putchar(' ');
1937 for (i = 0; i < n; ++i)
1938 printf("%.2x", val[i]);
1939 for (; i < size; ++i)
1940 printf("%s", fault_chars[fault_type]);
1942 putchar(' ');
1943 inc = size;
1944 nslash = 0;
1945 for(;;){
1946 if( scanhex(&n) ){
1947 for (i = 0; i < size; ++i)
1948 val[i] = n >> (i * 8);
1949 if (!brev)
1950 byterev(val, size);
1951 mwrite(adrs, val, size);
1952 inc = size;
1954 cmd = skipbl();
1955 if (cmd == '\n')
1956 break;
1957 inc = 0;
1958 switch (cmd) {
1959 case '\'':
1960 for(;;){
1961 n = inchar();
1962 if( n == '\\' )
1963 n = bsesc();
1964 else if( n == '\'' )
1965 break;
1966 for (i = 0; i < size; ++i)
1967 val[i] = n >> (i * 8);
1968 if (!brev)
1969 byterev(val, size);
1970 mwrite(adrs, val, size);
1971 adrs += size;
1973 adrs -= size;
1974 inc = size;
1975 break;
1976 case ',':
1977 adrs += size;
1978 break;
1979 case '.':
1980 mnoread = 0;
1981 break;
1982 case ';':
1983 break;
1984 case 'x':
1985 case EOF:
1986 scannl();
1987 return;
1988 case 'b':
1989 case 'v':
1990 size = 1;
1991 break;
1992 case 'w':
1993 size = 2;
1994 break;
1995 case 'l':
1996 size = 4;
1997 break;
1998 case 'u':
1999 size = 8;
2000 break;
2001 case '^':
2002 adrs -= size;
2003 break;
2004 case '/':
2005 if (nslash > 0)
2006 adrs -= 1 << nslash;
2007 else
2008 nslash = 0;
2009 nslash += 4;
2010 adrs += 1 << nslash;
2011 break;
2012 case '\\':
2013 if (nslash < 0)
2014 adrs += 1 << -nslash;
2015 else
2016 nslash = 0;
2017 nslash -= 4;
2018 adrs -= 1 << -nslash;
2019 break;
2020 case 'm':
2021 scanhex((void *)&adrs);
2022 break;
2023 case 'n':
2024 mnoread = 1;
2025 break;
2026 case 'r':
2027 brev = !brev;
2028 break;
2029 case '<':
2030 n = size;
2031 scanhex(&n);
2032 adrs -= n;
2033 break;
2034 case '>':
2035 n = size;
2036 scanhex(&n);
2037 adrs += n;
2038 break;
2039 case '?':
2040 printf(memex_subcmd_help_string);
2041 break;
2044 adrs += inc;
2048 static int
2049 bsesc(void)
2051 int c;
2053 c = inchar();
2054 switch( c ){
2055 case 'n': c = '\n'; break;
2056 case 'r': c = '\r'; break;
2057 case 'b': c = '\b'; break;
2058 case 't': c = '\t'; break;
2060 return c;
2063 static void xmon_rawdump (unsigned long adrs, long ndump)
2065 long n, m, r, nr;
2066 unsigned char temp[16];
2068 for (n = ndump; n > 0;) {
2069 r = n < 16? n: 16;
2070 nr = mread(adrs, temp, r);
2071 adrs += nr;
2072 for (m = 0; m < r; ++m) {
2073 if (m < nr)
2074 printf("%.2x", temp[m]);
2075 else
2076 printf("%s", fault_chars[fault_type]);
2078 n -= r;
2079 if (nr < r)
2080 break;
2082 printf("\n");
2085 #ifdef CONFIG_PPC64
2086 static void dump_one_paca(int cpu)
2088 struct paca_struct *p;
2089 #ifdef CONFIG_PPC_STD_MMU_64
2090 int i = 0;
2091 #endif
2093 if (setjmp(bus_error_jmp) != 0) {
2094 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2095 return;
2098 catch_memory_errors = 1;
2099 sync();
2101 p = &paca[cpu];
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");
2123 #endif
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++) {
2130 u64 esid, vsid;
2132 if (!p->slb_shadow_ptr)
2133 continue;
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);
2138 if (esid || vsid) {
2139 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2140 i, esid, vsid);
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]);
2147 #endif
2148 DUMP(p, dscr_default, "llx");
2149 #ifdef CONFIG_PPC_BOOK3E
2150 DUMP(p, pgd, "p");
2151 DUMP(p, kernel_pgd, "p");
2152 DUMP(p, tcd_ptr, "p");
2153 DUMP(p, mc_kstack, "p");
2154 DUMP(p, crit_kstack, "p");
2155 DUMP(p, dbg_kstack, "p");
2156 #endif
2157 DUMP(p, __current, "p");
2158 DUMP(p, kstack, "lx");
2159 DUMP(p, stab_rr, "lx");
2160 DUMP(p, saved_r1, "lx");
2161 DUMP(p, trap_save, "x");
2162 DUMP(p, soft_enabled, "x");
2163 DUMP(p, irq_happened, "x");
2164 DUMP(p, io_sync, "x");
2165 DUMP(p, irq_work_pending, "x");
2166 DUMP(p, nap_state_lost, "x");
2167 DUMP(p, sprg_vdso, "llx");
2169 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2170 DUMP(p, tm_scratch, "llx");
2171 #endif
2173 #ifdef CONFIG_PPC_POWERNV
2174 DUMP(p, core_idle_state_ptr, "p");
2175 DUMP(p, thread_idle_state, "x");
2176 DUMP(p, thread_mask, "x");
2177 DUMP(p, subcore_sibling_mask, "x");
2178 #endif
2180 DUMP(p, user_time, "llx");
2181 DUMP(p, system_time, "llx");
2182 DUMP(p, user_time_scaled, "llx");
2183 DUMP(p, starttime, "llx");
2184 DUMP(p, starttime_user, "llx");
2185 DUMP(p, startspurr, "llx");
2186 DUMP(p, utime_sspurr, "llx");
2187 DUMP(p, stolen_time, "llx");
2188 #undef DUMP
2190 catch_memory_errors = 0;
2191 sync();
2194 static void dump_all_pacas(void)
2196 int cpu;
2198 if (num_possible_cpus() == 0) {
2199 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2200 return;
2203 for_each_possible_cpu(cpu)
2204 dump_one_paca(cpu);
2207 static void dump_pacas(void)
2209 unsigned long num;
2210 int c;
2212 c = inchar();
2213 if (c == 'a') {
2214 dump_all_pacas();
2215 return;
2218 termch = c; /* Put c back, it wasn't 'a' */
2220 if (scanhex(&num))
2221 dump_one_paca(num);
2222 else
2223 dump_one_paca(xmon_owner);
2225 #endif
2227 static void
2228 dump(void)
2230 int c;
2232 c = inchar();
2234 #ifdef CONFIG_PPC64
2235 if (c == 'p') {
2236 xmon_start_pagination();
2237 dump_pacas();
2238 xmon_end_pagination();
2239 return;
2241 #endif
2243 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2244 termch = c;
2245 scanhex((void *)&adrs);
2246 if (termch != '\n')
2247 termch = 0;
2248 if (c == 'i') {
2249 scanhex(&nidump);
2250 if (nidump == 0)
2251 nidump = 16;
2252 else if (nidump > MAX_DUMP)
2253 nidump = MAX_DUMP;
2254 adrs += ppc_inst_dump(adrs, nidump, 1);
2255 last_cmd = "di\n";
2256 } else if (c == 'l') {
2257 dump_log_buf();
2258 } else if (c == 'r') {
2259 scanhex(&ndump);
2260 if (ndump == 0)
2261 ndump = 64;
2262 xmon_rawdump(adrs, ndump);
2263 adrs += ndump;
2264 last_cmd = "dr\n";
2265 } else {
2266 scanhex(&ndump);
2267 if (ndump == 0)
2268 ndump = 64;
2269 else if (ndump > MAX_DUMP)
2270 ndump = MAX_DUMP;
2271 prdump(adrs, ndump);
2272 adrs += ndump;
2273 last_cmd = "d\n";
2277 static void
2278 prdump(unsigned long adrs, long ndump)
2280 long n, m, c, r, nr;
2281 unsigned char temp[16];
2283 for (n = ndump; n > 0;) {
2284 printf(REG, adrs);
2285 putchar(' ');
2286 r = n < 16? n: 16;
2287 nr = mread(adrs, temp, r);
2288 adrs += nr;
2289 for (m = 0; m < r; ++m) {
2290 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2291 putchar(' ');
2292 if (m < nr)
2293 printf("%.2x", temp[m]);
2294 else
2295 printf("%s", fault_chars[fault_type]);
2297 for (; m < 16; ++m) {
2298 if ((m & (sizeof(long) - 1)) == 0)
2299 putchar(' ');
2300 printf(" ");
2302 printf(" |");
2303 for (m = 0; m < r; ++m) {
2304 if (m < nr) {
2305 c = temp[m];
2306 putchar(' ' <= c && c <= '~'? c: '.');
2307 } else
2308 putchar(' ');
2310 n -= r;
2311 for (; m < 16; ++m)
2312 putchar(' ');
2313 printf("|\n");
2314 if (nr < r)
2315 break;
2319 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2321 static int
2322 generic_inst_dump(unsigned long adr, long count, int praddr,
2323 instruction_dump_func dump_func)
2325 int nr, dotted;
2326 unsigned long first_adr;
2327 unsigned long inst, last_inst = 0;
2328 unsigned char val[4];
2330 dotted = 0;
2331 for (first_adr = adr; count > 0; --count, adr += 4) {
2332 nr = mread(adr, val, 4);
2333 if (nr == 0) {
2334 if (praddr) {
2335 const char *x = fault_chars[fault_type];
2336 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2338 break;
2340 inst = GETWORD(val);
2341 if (adr > first_adr && inst == last_inst) {
2342 if (!dotted) {
2343 printf(" ...\n");
2344 dotted = 1;
2346 continue;
2348 dotted = 0;
2349 last_inst = inst;
2350 if (praddr)
2351 printf(REG" %.8x", adr, inst);
2352 printf("\t");
2353 dump_func(inst, adr);
2354 printf("\n");
2356 return adr - first_adr;
2359 static int
2360 ppc_inst_dump(unsigned long adr, long count, int praddr)
2362 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2365 void
2366 print_address(unsigned long addr)
2368 xmon_print_symbol(addr, "\t# ", "");
2371 void
2372 dump_log_buf(void)
2374 struct kmsg_dumper dumper = { .active = 1 };
2375 unsigned char buf[128];
2376 size_t len;
2378 if (setjmp(bus_error_jmp) != 0) {
2379 printf("Error dumping printk buffer!\n");
2380 return;
2383 catch_memory_errors = 1;
2384 sync();
2386 kmsg_dump_rewind_nolock(&dumper);
2387 xmon_start_pagination();
2388 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2389 buf[len] = '\0';
2390 printf("%s", buf);
2392 xmon_end_pagination();
2394 sync();
2395 /* wait a little while to see if we get a machine check */
2396 __delay(200);
2397 catch_memory_errors = 0;
2401 * Memory operations - move, set, print differences
2403 static unsigned long mdest; /* destination address */
2404 static unsigned long msrc; /* source address */
2405 static unsigned long mval; /* byte value to set memory to */
2406 static unsigned long mcount; /* # bytes to affect */
2407 static unsigned long mdiffs; /* max # differences to print */
2409 static void
2410 memops(int cmd)
2412 scanhex((void *)&mdest);
2413 if( termch != '\n' )
2414 termch = 0;
2415 scanhex((void *)(cmd == 's'? &mval: &msrc));
2416 if( termch != '\n' )
2417 termch = 0;
2418 scanhex((void *)&mcount);
2419 switch( cmd ){
2420 case 'm':
2421 memmove((void *)mdest, (void *)msrc, mcount);
2422 break;
2423 case 's':
2424 memset((void *)mdest, mval, mcount);
2425 break;
2426 case 'd':
2427 if( termch != '\n' )
2428 termch = 0;
2429 scanhex((void *)&mdiffs);
2430 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2431 break;
2435 static void
2436 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2438 unsigned n, prt;
2440 prt = 0;
2441 for( n = nb; n > 0; --n )
2442 if( *p1++ != *p2++ )
2443 if( ++prt <= maxpr )
2444 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2445 p1[-1], p2 - 1, p2[-1]);
2446 if( prt > maxpr )
2447 printf("Total of %d differences\n", prt);
2450 static unsigned mend;
2451 static unsigned mask;
2453 static void
2454 memlocate(void)
2456 unsigned a, n;
2457 unsigned char val[4];
2459 last_cmd = "ml";
2460 scanhex((void *)&mdest);
2461 if (termch != '\n') {
2462 termch = 0;
2463 scanhex((void *)&mend);
2464 if (termch != '\n') {
2465 termch = 0;
2466 scanhex((void *)&mval);
2467 mask = ~0;
2468 if (termch != '\n') termch = 0;
2469 scanhex((void *)&mask);
2472 n = 0;
2473 for (a = mdest; a < mend; a += 4) {
2474 if (mread(a, val, 4) == 4
2475 && ((GETWORD(val) ^ mval) & mask) == 0) {
2476 printf("%.16x: %.16x\n", a, GETWORD(val));
2477 if (++n >= 10)
2478 break;
2483 static unsigned long mskip = 0x1000;
2484 static unsigned long mlim = 0xffffffff;
2486 static void
2487 memzcan(void)
2489 unsigned char v;
2490 unsigned a;
2491 int ok, ook;
2493 scanhex(&mdest);
2494 if (termch != '\n') termch = 0;
2495 scanhex(&mskip);
2496 if (termch != '\n') termch = 0;
2497 scanhex(&mlim);
2498 ook = 0;
2499 for (a = mdest; a < mlim; a += mskip) {
2500 ok = mread(a, &v, 1);
2501 if (ok && !ook) {
2502 printf("%.8x .. ", a);
2503 } else if (!ok && ook)
2504 printf("%.8x\n", a - mskip);
2505 ook = ok;
2506 if (a + mskip < a)
2507 break;
2509 if (ook)
2510 printf("%.8x\n", a - mskip);
2513 static void proccall(void)
2515 unsigned long args[8];
2516 unsigned long ret;
2517 int i;
2518 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2519 unsigned long, unsigned long, unsigned long,
2520 unsigned long, unsigned long, unsigned long);
2521 callfunc_t func;
2523 if (!scanhex(&adrs))
2524 return;
2525 if (termch != '\n')
2526 termch = 0;
2527 for (i = 0; i < 8; ++i)
2528 args[i] = 0;
2529 for (i = 0; i < 8; ++i) {
2530 if (!scanhex(&args[i]) || termch == '\n')
2531 break;
2532 termch = 0;
2534 func = (callfunc_t) adrs;
2535 ret = 0;
2536 if (setjmp(bus_error_jmp) == 0) {
2537 catch_memory_errors = 1;
2538 sync();
2539 ret = func(args[0], args[1], args[2], args[3],
2540 args[4], args[5], args[6], args[7]);
2541 sync();
2542 printf("return value is 0x%lx\n", ret);
2543 } else {
2544 printf("*** %x exception occurred\n", fault_except);
2546 catch_memory_errors = 0;
2549 /* Input scanning routines */
2551 skipbl(void)
2553 int c;
2555 if( termch != 0 ){
2556 c = termch;
2557 termch = 0;
2558 } else
2559 c = inchar();
2560 while( c == ' ' || c == '\t' )
2561 c = inchar();
2562 return c;
2565 #define N_PTREGS 44
2566 static char *regnames[N_PTREGS] = {
2567 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2568 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2569 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2570 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2571 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2572 #ifdef CONFIG_PPC64
2573 "softe",
2574 #else
2575 "mq",
2576 #endif
2577 "trap", "dar", "dsisr", "res"
2581 scanhex(unsigned long *vp)
2583 int c, d;
2584 unsigned long v;
2586 c = skipbl();
2587 if (c == '%') {
2588 /* parse register name */
2589 char regname[8];
2590 int i;
2592 for (i = 0; i < sizeof(regname) - 1; ++i) {
2593 c = inchar();
2594 if (!isalnum(c)) {
2595 termch = c;
2596 break;
2598 regname[i] = c;
2600 regname[i] = 0;
2601 for (i = 0; i < N_PTREGS; ++i) {
2602 if (strcmp(regnames[i], regname) == 0) {
2603 if (xmon_regs == NULL) {
2604 printf("regs not available\n");
2605 return 0;
2607 *vp = ((unsigned long *)xmon_regs)[i];
2608 return 1;
2611 printf("invalid register name '%%%s'\n", regname);
2612 return 0;
2615 /* skip leading "0x" if any */
2617 if (c == '0') {
2618 c = inchar();
2619 if (c == 'x') {
2620 c = inchar();
2621 } else {
2622 d = hexdigit(c);
2623 if (d == EOF) {
2624 termch = c;
2625 *vp = 0;
2626 return 1;
2629 } else if (c == '$') {
2630 int i;
2631 for (i=0; i<63; i++) {
2632 c = inchar();
2633 if (isspace(c) || c == '\0') {
2634 termch = c;
2635 break;
2637 tmpstr[i] = c;
2639 tmpstr[i++] = 0;
2640 *vp = 0;
2641 if (setjmp(bus_error_jmp) == 0) {
2642 catch_memory_errors = 1;
2643 sync();
2644 *vp = kallsyms_lookup_name(tmpstr);
2645 sync();
2647 catch_memory_errors = 0;
2648 if (!(*vp)) {
2649 printf("unknown symbol '%s'\n", tmpstr);
2650 return 0;
2652 return 1;
2655 d = hexdigit(c);
2656 if (d == EOF) {
2657 termch = c;
2658 return 0;
2660 v = 0;
2661 do {
2662 v = (v << 4) + d;
2663 c = inchar();
2664 d = hexdigit(c);
2665 } while (d != EOF);
2666 termch = c;
2667 *vp = v;
2668 return 1;
2671 static void
2672 scannl(void)
2674 int c;
2676 c = termch;
2677 termch = 0;
2678 while( c != '\n' )
2679 c = inchar();
2682 static int hexdigit(int c)
2684 if( '0' <= c && c <= '9' )
2685 return c - '0';
2686 if( 'A' <= c && c <= 'F' )
2687 return c - ('A' - 10);
2688 if( 'a' <= c && c <= 'f' )
2689 return c - ('a' - 10);
2690 return EOF;
2693 void
2694 getstring(char *s, int size)
2696 int c;
2698 c = skipbl();
2699 do {
2700 if( size > 1 ){
2701 *s++ = c;
2702 --size;
2704 c = inchar();
2705 } while( c != ' ' && c != '\t' && c != '\n' );
2706 termch = c;
2707 *s = 0;
2710 static char line[256];
2711 static char *lineptr;
2713 static void
2714 flush_input(void)
2716 lineptr = NULL;
2719 static int
2720 inchar(void)
2722 if (lineptr == NULL || *lineptr == 0) {
2723 if (xmon_gets(line, sizeof(line)) == NULL) {
2724 lineptr = NULL;
2725 return EOF;
2727 lineptr = line;
2729 return *lineptr++;
2732 static void
2733 take_input(char *str)
2735 lineptr = str;
2739 static void
2740 symbol_lookup(void)
2742 int type = inchar();
2743 unsigned long addr;
2744 static char tmp[64];
2746 switch (type) {
2747 case 'a':
2748 if (scanhex(&addr))
2749 xmon_print_symbol(addr, ": ", "\n");
2750 termch = 0;
2751 break;
2752 case 's':
2753 getstring(tmp, 64);
2754 if (setjmp(bus_error_jmp) == 0) {
2755 catch_memory_errors = 1;
2756 sync();
2757 addr = kallsyms_lookup_name(tmp);
2758 if (addr)
2759 printf("%s: %lx\n", tmp, addr);
2760 else
2761 printf("Symbol '%s' not found.\n", tmp);
2762 sync();
2764 catch_memory_errors = 0;
2765 termch = 0;
2766 break;
2771 /* Print an address in numeric and symbolic form (if possible) */
2772 static void xmon_print_symbol(unsigned long address, const char *mid,
2773 const char *after)
2775 char *modname;
2776 const char *name = NULL;
2777 unsigned long offset, size;
2779 printf(REG, address);
2780 if (setjmp(bus_error_jmp) == 0) {
2781 catch_memory_errors = 1;
2782 sync();
2783 name = kallsyms_lookup(address, &size, &offset, &modname,
2784 tmpstr);
2785 sync();
2786 /* wait a little while to see if we get a machine check */
2787 __delay(200);
2790 catch_memory_errors = 0;
2792 if (name) {
2793 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2794 if (modname)
2795 printf(" [%s]", modname);
2797 printf("%s", after);
2800 #ifdef CONFIG_PPC_BOOK3S_64
2801 void dump_segments(void)
2803 int i;
2804 unsigned long esid,vsid;
2805 unsigned long llp;
2807 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2809 for (i = 0; i < mmu_slb_size; i++) {
2810 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2811 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2812 if (esid || vsid) {
2813 printf("%02d %016lx %016lx", i, esid, vsid);
2814 if (esid & SLB_ESID_V) {
2815 llp = vsid & SLB_VSID_LLP;
2816 if (vsid & SLB_VSID_B_1T) {
2817 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2818 GET_ESID_1T(esid),
2819 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2820 llp);
2821 } else {
2822 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2823 GET_ESID(esid),
2824 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2825 llp);
2827 } else
2828 printf("\n");
2832 #endif
2834 #ifdef CONFIG_PPC_STD_MMU_32
2835 void dump_segments(void)
2837 int i;
2839 printf("sr0-15 =");
2840 for (i = 0; i < 16; ++i)
2841 printf(" %x", mfsrin(i));
2842 printf("\n");
2844 #endif
2846 #ifdef CONFIG_44x
2847 static void dump_tlb_44x(void)
2849 int i;
2851 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2852 unsigned long w0,w1,w2;
2853 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2854 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2855 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2856 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2857 if (w0 & PPC44x_TLB_VALID) {
2858 printf("V %08x -> %01x%08x %c%c%c%c%c",
2859 w0 & PPC44x_TLB_EPN_MASK,
2860 w1 & PPC44x_TLB_ERPN_MASK,
2861 w1 & PPC44x_TLB_RPN_MASK,
2862 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2863 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2864 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2865 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2866 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2868 printf("\n");
2871 #endif /* CONFIG_44x */
2873 #ifdef CONFIG_PPC_BOOK3E
2874 static void dump_tlb_book3e(void)
2876 u32 mmucfg, pidmask, lpidmask;
2877 u64 ramask;
2878 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2879 int mmu_version;
2880 static const char *pgsz_names[] = {
2881 " 1K",
2882 " 2K",
2883 " 4K",
2884 " 8K",
2885 " 16K",
2886 " 32K",
2887 " 64K",
2888 "128K",
2889 "256K",
2890 "512K",
2891 " 1M",
2892 " 2M",
2893 " 4M",
2894 " 8M",
2895 " 16M",
2896 " 32M",
2897 " 64M",
2898 "128M",
2899 "256M",
2900 "512M",
2901 " 1G",
2902 " 2G",
2903 " 4G",
2904 " 8G",
2905 " 16G",
2906 " 32G",
2907 " 64G",
2908 "128G",
2909 "256G",
2910 "512G",
2911 " 1T",
2912 " 2T",
2915 /* Gather some infos about the MMU */
2916 mmucfg = mfspr(SPRN_MMUCFG);
2917 mmu_version = (mmucfg & 3) + 1;
2918 ntlbs = ((mmucfg >> 2) & 3) + 1;
2919 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2920 lpidsz = (mmucfg >> 24) & 0xf;
2921 rasz = (mmucfg >> 16) & 0x7f;
2922 if ((mmu_version > 1) && (mmucfg & 0x10000))
2923 lrat = 1;
2924 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2925 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2926 pidmask = (1ul << pidsz) - 1;
2927 lpidmask = (1ul << lpidsz) - 1;
2928 ramask = (1ull << rasz) - 1;
2930 for (tlb = 0; tlb < ntlbs; tlb++) {
2931 u32 tlbcfg;
2932 int nent, assoc, new_cc = 1;
2933 printf("TLB %d:\n------\n", tlb);
2934 switch(tlb) {
2935 case 0:
2936 tlbcfg = mfspr(SPRN_TLB0CFG);
2937 break;
2938 case 1:
2939 tlbcfg = mfspr(SPRN_TLB1CFG);
2940 break;
2941 case 2:
2942 tlbcfg = mfspr(SPRN_TLB2CFG);
2943 break;
2944 case 3:
2945 tlbcfg = mfspr(SPRN_TLB3CFG);
2946 break;
2947 default:
2948 printf("Unsupported TLB number !\n");
2949 continue;
2951 nent = tlbcfg & 0xfff;
2952 assoc = (tlbcfg >> 24) & 0xff;
2953 for (i = 0; i < nent; i++) {
2954 u32 mas0 = MAS0_TLBSEL(tlb);
2955 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2956 u64 mas2 = 0;
2957 u64 mas7_mas3;
2958 int esel = i, cc = i;
2960 if (assoc != 0) {
2961 cc = i / assoc;
2962 esel = i % assoc;
2963 mas2 = cc * 0x1000;
2966 mas0 |= MAS0_ESEL(esel);
2967 mtspr(SPRN_MAS0, mas0);
2968 mtspr(SPRN_MAS1, mas1);
2969 mtspr(SPRN_MAS2, mas2);
2970 asm volatile("tlbre 0,0,0" : : : "memory");
2971 mas1 = mfspr(SPRN_MAS1);
2972 mas2 = mfspr(SPRN_MAS2);
2973 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2974 if (assoc && (i % assoc) == 0)
2975 new_cc = 1;
2976 if (!(mas1 & MAS1_VALID))
2977 continue;
2978 if (assoc == 0)
2979 printf("%04x- ", i);
2980 else if (new_cc)
2981 printf("%04x-%c", cc, 'A' + esel);
2982 else
2983 printf(" |%c", 'A' + esel);
2984 new_cc = 0;
2985 printf(" %016llx %04x %s %c%c AS%c",
2986 mas2 & ~0x3ffull,
2987 (mas1 >> 16) & 0x3fff,
2988 pgsz_names[(mas1 >> 7) & 0x1f],
2989 mas1 & MAS1_IND ? 'I' : ' ',
2990 mas1 & MAS1_IPROT ? 'P' : ' ',
2991 mas1 & MAS1_TS ? '1' : '0');
2992 printf(" %c%c%c%c%c%c%c",
2993 mas2 & MAS2_X0 ? 'a' : ' ',
2994 mas2 & MAS2_X1 ? 'v' : ' ',
2995 mas2 & MAS2_W ? 'w' : ' ',
2996 mas2 & MAS2_I ? 'i' : ' ',
2997 mas2 & MAS2_M ? 'm' : ' ',
2998 mas2 & MAS2_G ? 'g' : ' ',
2999 mas2 & MAS2_E ? 'e' : ' ');
3000 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3001 if (mas1 & MAS1_IND)
3002 printf(" %s\n",
3003 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3004 else
3005 printf(" U%c%c%c S%c%c%c\n",
3006 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3007 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3008 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3009 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3010 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3011 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3015 #endif /* CONFIG_PPC_BOOK3E */
3017 static void xmon_init(int enable)
3019 if (enable) {
3020 __debugger = xmon;
3021 __debugger_ipi = xmon_ipi;
3022 __debugger_bpt = xmon_bpt;
3023 __debugger_sstep = xmon_sstep;
3024 __debugger_iabr_match = xmon_iabr_match;
3025 __debugger_break_match = xmon_break_match;
3026 __debugger_fault_handler = xmon_fault_handler;
3027 } else {
3028 __debugger = NULL;
3029 __debugger_ipi = NULL;
3030 __debugger_bpt = NULL;
3031 __debugger_sstep = NULL;
3032 __debugger_iabr_match = NULL;
3033 __debugger_break_match = NULL;
3034 __debugger_fault_handler = NULL;
3038 #ifdef CONFIG_MAGIC_SYSRQ
3039 static void sysrq_handle_xmon(int key)
3041 /* ensure xmon is enabled */
3042 xmon_init(1);
3043 debugger(get_irq_regs());
3046 static struct sysrq_key_op sysrq_xmon_op = {
3047 .handler = sysrq_handle_xmon,
3048 .help_msg = "xmon(x)",
3049 .action_msg = "Entering xmon",
3052 static int __init setup_xmon_sysrq(void)
3054 register_sysrq_key('x', &sysrq_xmon_op);
3055 return 0;
3057 __initcall(setup_xmon_sysrq);
3058 #endif /* CONFIG_MAGIC_SYSRQ */
3060 static int __initdata xmon_early, xmon_off;
3062 static int __init early_parse_xmon(char *p)
3064 if (!p || strncmp(p, "early", 5) == 0) {
3065 /* just "xmon" is equivalent to "xmon=early" */
3066 xmon_init(1);
3067 xmon_early = 1;
3068 } else if (strncmp(p, "on", 2) == 0)
3069 xmon_init(1);
3070 else if (strncmp(p, "off", 3) == 0)
3071 xmon_off = 1;
3072 else if (strncmp(p, "nobt", 4) == 0)
3073 xmon_no_auto_backtrace = 1;
3074 else
3075 return 1;
3077 return 0;
3079 early_param("xmon", early_parse_xmon);
3081 void __init xmon_setup(void)
3083 #ifdef CONFIG_XMON_DEFAULT
3084 if (!xmon_off)
3085 xmon_init(1);
3086 #endif
3087 if (xmon_early)
3088 debugger(NULL);
3091 #ifdef CONFIG_SPU_BASE
3093 struct spu_info {
3094 struct spu *spu;
3095 u64 saved_mfc_sr1_RW;
3096 u32 saved_spu_runcntl_RW;
3097 unsigned long dump_addr;
3098 u8 stopped_ok;
3101 #define XMON_NUM_SPUS 16 /* Enough for current hardware */
3103 static struct spu_info spu_info[XMON_NUM_SPUS];
3105 void xmon_register_spus(struct list_head *list)
3107 struct spu *spu;
3109 list_for_each_entry(spu, list, full_list) {
3110 if (spu->number >= XMON_NUM_SPUS) {
3111 WARN_ON(1);
3112 continue;
3115 spu_info[spu->number].spu = spu;
3116 spu_info[spu->number].stopped_ok = 0;
3117 spu_info[spu->number].dump_addr = (unsigned long)
3118 spu_info[spu->number].spu->local_store;
3122 static void stop_spus(void)
3124 struct spu *spu;
3125 int i;
3126 u64 tmp;
3128 for (i = 0; i < XMON_NUM_SPUS; i++) {
3129 if (!spu_info[i].spu)
3130 continue;
3132 if (setjmp(bus_error_jmp) == 0) {
3133 catch_memory_errors = 1;
3134 sync();
3136 spu = spu_info[i].spu;
3138 spu_info[i].saved_spu_runcntl_RW =
3139 in_be32(&spu->problem->spu_runcntl_RW);
3141 tmp = spu_mfc_sr1_get(spu);
3142 spu_info[i].saved_mfc_sr1_RW = tmp;
3144 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3145 spu_mfc_sr1_set(spu, tmp);
3147 sync();
3148 __delay(200);
3150 spu_info[i].stopped_ok = 1;
3152 printf("Stopped spu %.2d (was %s)\n", i,
3153 spu_info[i].saved_spu_runcntl_RW ?
3154 "running" : "stopped");
3155 } else {
3156 catch_memory_errors = 0;
3157 printf("*** Error stopping spu %.2d\n", i);
3159 catch_memory_errors = 0;
3163 static void restart_spus(void)
3165 struct spu *spu;
3166 int i;
3168 for (i = 0; i < XMON_NUM_SPUS; i++) {
3169 if (!spu_info[i].spu)
3170 continue;
3172 if (!spu_info[i].stopped_ok) {
3173 printf("*** Error, spu %d was not successfully stopped"
3174 ", not restarting\n", i);
3175 continue;
3178 if (setjmp(bus_error_jmp) == 0) {
3179 catch_memory_errors = 1;
3180 sync();
3182 spu = spu_info[i].spu;
3183 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3184 out_be32(&spu->problem->spu_runcntl_RW,
3185 spu_info[i].saved_spu_runcntl_RW);
3187 sync();
3188 __delay(200);
3190 printf("Restarted spu %.2d\n", i);
3191 } else {
3192 catch_memory_errors = 0;
3193 printf("*** Error restarting spu %.2d\n", i);
3195 catch_memory_errors = 0;
3199 #define DUMP_WIDTH 23
3200 #define DUMP_VALUE(format, field, value) \
3201 do { \
3202 if (setjmp(bus_error_jmp) == 0) { \
3203 catch_memory_errors = 1; \
3204 sync(); \
3205 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3206 #field, value); \
3207 sync(); \
3208 __delay(200); \
3209 } else { \
3210 catch_memory_errors = 0; \
3211 printf(" %-*s = *** Error reading field.\n", \
3212 DUMP_WIDTH, #field); \
3214 catch_memory_errors = 0; \
3215 } while (0)
3217 #define DUMP_FIELD(obj, format, field) \
3218 DUMP_VALUE(format, field, obj->field)
3220 static void dump_spu_fields(struct spu *spu)
3222 printf("Dumping spu fields at address %p:\n", spu);
3224 DUMP_FIELD(spu, "0x%x", number);
3225 DUMP_FIELD(spu, "%s", name);
3226 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3227 DUMP_FIELD(spu, "0x%p", local_store);
3228 DUMP_FIELD(spu, "0x%lx", ls_size);
3229 DUMP_FIELD(spu, "0x%x", node);
3230 DUMP_FIELD(spu, "0x%lx", flags);
3231 DUMP_FIELD(spu, "%d", class_0_pending);
3232 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3233 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3234 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3235 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3236 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3237 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3238 DUMP_FIELD(spu, "0x%x", slb_replace);
3239 DUMP_FIELD(spu, "%d", pid);
3240 DUMP_FIELD(spu, "0x%p", mm);
3241 DUMP_FIELD(spu, "0x%p", ctx);
3242 DUMP_FIELD(spu, "0x%p", rq);
3243 DUMP_FIELD(spu, "0x%p", timestamp);
3244 DUMP_FIELD(spu, "0x%lx", problem_phys);
3245 DUMP_FIELD(spu, "0x%p", problem);
3246 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3247 in_be32(&spu->problem->spu_runcntl_RW));
3248 DUMP_VALUE("0x%x", problem->spu_status_R,
3249 in_be32(&spu->problem->spu_status_R));
3250 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3251 in_be32(&spu->problem->spu_npc_RW));
3252 DUMP_FIELD(spu, "0x%p", priv2);
3253 DUMP_FIELD(spu, "0x%p", pdata);
3257 spu_inst_dump(unsigned long adr, long count, int praddr)
3259 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3262 static void dump_spu_ls(unsigned long num, int subcmd)
3264 unsigned long offset, addr, ls_addr;
3266 if (setjmp(bus_error_jmp) == 0) {
3267 catch_memory_errors = 1;
3268 sync();
3269 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3270 sync();
3271 __delay(200);
3272 } else {
3273 catch_memory_errors = 0;
3274 printf("*** Error: accessing spu info for spu %d\n", num);
3275 return;
3277 catch_memory_errors = 0;
3279 if (scanhex(&offset))
3280 addr = ls_addr + offset;
3281 else
3282 addr = spu_info[num].dump_addr;
3284 if (addr >= ls_addr + LS_SIZE) {
3285 printf("*** Error: address outside of local store\n");
3286 return;
3289 switch (subcmd) {
3290 case 'i':
3291 addr += spu_inst_dump(addr, 16, 1);
3292 last_cmd = "sdi\n";
3293 break;
3294 default:
3295 prdump(addr, 64);
3296 addr += 64;
3297 last_cmd = "sd\n";
3298 break;
3301 spu_info[num].dump_addr = addr;
3304 static int do_spu_cmd(void)
3306 static unsigned long num = 0;
3307 int cmd, subcmd = 0;
3309 cmd = inchar();
3310 switch (cmd) {
3311 case 's':
3312 stop_spus();
3313 break;
3314 case 'r':
3315 restart_spus();
3316 break;
3317 case 'd':
3318 subcmd = inchar();
3319 if (isxdigit(subcmd) || subcmd == '\n')
3320 termch = subcmd;
3321 case 'f':
3322 scanhex(&num);
3323 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3324 printf("*** Error: invalid spu number\n");
3325 return 0;
3328 switch (cmd) {
3329 case 'f':
3330 dump_spu_fields(spu_info[num].spu);
3331 break;
3332 default:
3333 dump_spu_ls(num, subcmd);
3334 break;
3337 break;
3338 default:
3339 return -1;
3342 return 0;
3344 #else /* ! CONFIG_SPU_BASE */
3345 static int do_spu_cmd(void)
3347 return -1;
3349 #endif