1
2
3
4
5
6
7
8
9
10
11
12
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>
29
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>
49
50#include <asm/opal.h>
51#include <asm/firmware.h>
52
53#ifdef CONFIG_PPC64
54#include <asm/hvcall.h>
55#include <asm/paca.h>
56#endif
57
58#if defined(CONFIG_PPC_SPLPAR)
59#include <asm/plpar_wrappers.h>
60#else
61static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
62#endif
63
64#include "nonstdio.h"
65#include "dis-asm.h"
66
67#ifdef CONFIG_SMP
68static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
69static unsigned long xmon_taken = 1;
70static int xmon_owner;
71static int xmon_gate;
72#else
73#define xmon_owner 0
74#endif
75
76static unsigned long in_xmon __read_mostly = 0;
77
78static unsigned long adrs;
79static int size = 1;
80#define MAX_DUMP (128 * 1024)
81static unsigned long ndump = 64;
82static unsigned long nidump = 16;
83static unsigned long ncsum = 4096;
84static int termch;
85static char tmpstr[128];
86
87static long bus_error_jmp[JMP_BUF_LEN];
88static int catch_memory_errors;
89static long *xmon_fault_jmp[NR_CPUS];
90
91
92struct bpt {
93 unsigned long address;
94 unsigned int instr[2];
95 atomic_t ref_count;
96 int enabled;
97 unsigned long pad;
98};
99
100
101#define BP_CIABR 1
102#define BP_TRAP 2
103#define BP_DABR 4
104
105#define NBPTS 256
106static struct bpt bpts[NBPTS];
107static struct bpt dabr;
108static struct bpt *iabr;
109static unsigned bpinstr = 0x7fe00008;
110
111#define BP_NUM(bp) ((bp) - bpts + 1)
112
113
114static int cmds(struct pt_regs *);
115static int mread(unsigned long, void *, int);
116static int mwrite(unsigned long, void *, int);
117static int handle_fault(struct pt_regs *);
118static void byterev(unsigned char *, int);
119static void memex(void);
120static int bsesc(void);
121static void dump(void);
122static void prdump(unsigned long, long);
123static int ppc_inst_dump(unsigned long, long, int);
124static void dump_log_buf(void);
125
126#ifdef CONFIG_PPC_POWERNV
127static void dump_opal_msglog(void);
128#else
129static inline void dump_opal_msglog(void)
130{
131 printf("Machine is not running OPAL firmware.\n");
132}
133#endif
134
135static void backtrace(struct pt_regs *);
136static void excprint(struct pt_regs *);
137static void prregs(struct pt_regs *);
138static void memops(int);
139static void memlocate(void);
140static void memzcan(void);
141static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
142int skipbl(void);
143int scanhex(unsigned long *valp);
144static void scannl(void);
145static int hexdigit(int);
146void getstring(char *, int);
147static void flush_input(void);
148static int inchar(void);
149static void take_input(char *);
150static unsigned long read_spr(int);
151static void write_spr(int, unsigned long);
152static void super_regs(void);
153static void remove_bpts(void);
154static void insert_bpts(void);
155static void remove_cpu_bpts(void);
156static void insert_cpu_bpts(void);
157static struct bpt *at_breakpoint(unsigned long pc);
158static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
159static int do_step(struct pt_regs *);
160static void bpt_cmds(void);
161static void cacheflush(void);
162static int cpu_cmd(void);
163static void csum(void);
164static void bootcmds(void);
165static void proccall(void);
166static void show_tasks(void);
167void dump_segments(void);
168static void symbol_lookup(void);
169static void xmon_show_stack(unsigned long sp, unsigned long lr,
170 unsigned long pc);
171static void xmon_print_symbol(unsigned long address, const char *mid,
172 const char *after);
173static const char *getvecname(unsigned long vec);
174
175static int do_spu_cmd(void);
176
177#ifdef CONFIG_44x
178static void dump_tlb_44x(void);
179#endif
180#ifdef CONFIG_PPC_BOOK3E
181static void dump_tlb_book3e(void);
182#endif
183
184static int xmon_no_auto_backtrace;
185
186extern void xmon_enter(void);
187extern void xmon_leave(void);
188
189#ifdef CONFIG_PPC64
190#define REG "%.16lx"
191#else
192#define REG "%.8lx"
193#endif
194
195#ifdef __LITTLE_ENDIAN__
196#define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
197#else
198#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
199#endif
200
201static char *help_string = "\
202Commands:\n\
203 b show breakpoints\n\
204 bd set data breakpoint\n\
205 bi set instruction breakpoint\n\
206 bc clear breakpoint\n"
207#ifdef CONFIG_SMP
208 "\
209 c print cpus stopped in xmon\n\
210 c# try to switch to cpu number h (in hex)\n"
211#endif
212 "\
213 C checksum\n\
214 d dump bytes\n\
215 di dump instructions\n\
216 df dump float values\n\
217 dd dump double values\n\
218 dl dump the kernel log buffer\n"
219#ifdef CONFIG_PPC_POWERNV
220 "\
221 do dump the OPAL message log\n"
222#endif
223#ifdef CONFIG_PPC64
224 "\
225 dp[#] dump paca for current cpu, or cpu #\n\
226 dpa dump paca for all possible cpus\n"
227#endif
228 "\
229 dr dump stream of raw bytes\n\
230 e print exception information\n\
231 f flush cache\n\
232 la lookup symbol+offset of specified address\n\
233 ls lookup address of specified symbol\n\
234 m examine/change memory\n\
235 mm move a block of memory\n\
236 ms set a block of memory\n\
237 md compare two blocks of memory\n\
238 ml locate a block of memory\n\
239 mz zero a block of memory\n\
240 mi show information about memory allocation\n\
241 p call a procedure\n\
242 P list processes/tasks\n\
243 r print registers\n\
244 s single step\n"
245#ifdef CONFIG_SPU_BASE
246" ss stop execution on all spus\n\
247 sr restore execution on stopped spus\n\
248 sf # dump spu fields for spu # (in hex)\n\
249 sd # dump spu local store for spu # (in hex)\n\
250 sdi # disassemble spu local store for spu # (in hex)\n"
251#endif
252" S print special registers\n\
253 t print backtrace\n\
254 x exit monitor and recover\n\
255 X exit monitor and don't recover\n"
256#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
257" u dump segment table or SLB\n"
258#elif defined(CONFIG_PPC_STD_MMU_32)
259" u dump segment registers\n"
260#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
261" u dump TLB\n"
262#endif
263" ? help\n"
264" # n limit output to n lines per page (for dp, dpa, dl)\n"
265" zr reboot\n\
266 zh halt\n"
267;
268
269static struct pt_regs *xmon_regs;
270
271static inline void sync(void)
272{
273 asm volatile("sync; isync");
274}
275
276static inline void store_inst(void *p)
277{
278 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
279}
280
281static inline void cflush(void *p)
282{
283 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
284}
285
286static inline void cinval(void *p)
287{
288 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
289}
290
291
292
293
294
295
296
297
298
299
300static void write_ciabr(unsigned long ciabr)
301{
302 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
303 return;
304
305 if (cpu_has_feature(CPU_FTR_HVMODE)) {
306 mtspr(SPRN_CIABR, ciabr);
307 return;
308 }
309 plapr_set_ciabr(ciabr);
310}
311
312
313
314
315
316
317
318
319static void set_ciabr(unsigned long addr)
320{
321 addr &= ~CIABR_PRIV;
322
323 if (cpu_has_feature(CPU_FTR_HVMODE))
324 addr |= CIABR_PRIV_HYPER;
325 else
326 addr |= CIABR_PRIV_SUPER;
327 write_ciabr(addr);
328}
329
330
331
332
333
334
335#define SURVEILLANCE_TOKEN 9000
336
337static inline void disable_surveillance(void)
338{
339#ifdef CONFIG_PPC_PSERIES
340
341 static struct rtas_args args;
342 int token;
343
344
345
346
347
348
349
350
351 token = rtas_token("set-indicator");
352 if (token == RTAS_UNKNOWN_SERVICE)
353 return;
354
355 rtas_call_unlocked(&args, token, 3, 1, NULL, SURVEILLANCE_TOKEN, 0, 0);
356
357#endif
358}
359
360#ifdef CONFIG_SMP
361static int xmon_speaker;
362
363static void get_output_lock(void)
364{
365 int me = smp_processor_id() + 0x100;
366 int last_speaker = 0, prev;
367 long timeout;
368
369 if (xmon_speaker == me)
370 return;
371
372 for (;;) {
373 last_speaker = cmpxchg(&xmon_speaker, 0, me);
374 if (last_speaker == 0)
375 return;
376
377
378
379
380
381 timeout = 10000;
382 while (xmon_speaker == last_speaker) {
383 if (--timeout > 0) {
384 udelay(100);
385 continue;
386 }
387
388
389 prev = cmpxchg(&xmon_speaker, last_speaker, me);
390 if (prev == last_speaker)
391 return;
392 break;
393 }
394 }
395}
396
397static void release_output_lock(void)
398{
399 xmon_speaker = 0;
400}
401
402int cpus_are_in_xmon(void)
403{
404 return !cpumask_empty(&cpus_in_xmon);
405}
406#endif
407
408static inline int unrecoverable_excp(struct pt_regs *regs)
409{
410#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
411
412 return 0;
413#else
414 return ((regs->msr & MSR_RI) == 0);
415#endif
416}
417
418static int xmon_core(struct pt_regs *regs, int fromipi)
419{
420 int cmd = 0;
421 struct bpt *bp;
422 long recurse_jmp[JMP_BUF_LEN];
423 unsigned long offset;
424 unsigned long flags;
425#ifdef CONFIG_SMP
426 int cpu;
427 int secondary;
428 unsigned long timeout;
429#endif
430
431 local_irq_save(flags);
432 hard_irq_disable();
433
434 bp = in_breakpoint_table(regs->nip, &offset);
435 if (bp != NULL) {
436 regs->nip = bp->address + offset;
437 atomic_dec(&bp->ref_count);
438 }
439
440 remove_cpu_bpts();
441
442#ifdef CONFIG_SMP
443 cpu = smp_processor_id();
444 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
445 get_output_lock();
446 excprint(regs);
447 printf("cpu 0x%x: Exception %lx %s in xmon, "
448 "returning to main loop\n",
449 cpu, regs->trap, getvecname(TRAP(regs)));
450 release_output_lock();
451 longjmp(xmon_fault_jmp[cpu], 1);
452 }
453
454 if (setjmp(recurse_jmp) != 0) {
455 if (!in_xmon || !xmon_gate) {
456 get_output_lock();
457 printf("xmon: WARNING: bad recursive fault "
458 "on cpu 0x%x\n", cpu);
459 release_output_lock();
460 goto waiting;
461 }
462 secondary = !(xmon_taken && cpu == xmon_owner);
463 goto cmdloop;
464 }
465
466 xmon_fault_jmp[cpu] = recurse_jmp;
467
468 bp = NULL;
469 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
470 bp = at_breakpoint(regs->nip);
471 if (bp || unrecoverable_excp(regs))
472 fromipi = 0;
473
474 if (!fromipi) {
475 get_output_lock();
476 excprint(regs);
477 if (bp) {
478 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
479 cpu, BP_NUM(bp));
480 xmon_print_symbol(regs->nip, " ", ")\n");
481 }
482 if (unrecoverable_excp(regs))
483 printf("WARNING: exception is not recoverable, "
484 "can't continue\n");
485 release_output_lock();
486 }
487
488 cpumask_set_cpu(cpu, &cpus_in_xmon);
489
490 waiting:
491 secondary = 1;
492 while (secondary && !xmon_gate) {
493 if (in_xmon == 0) {
494 if (fromipi)
495 goto leave;
496 secondary = test_and_set_bit(0, &in_xmon);
497 }
498 barrier();
499 }
500
501 if (!secondary && !xmon_gate) {
502
503
504 int ncpus = num_online_cpus();
505
506 xmon_owner = cpu;
507 mb();
508 if (ncpus > 1) {
509 smp_send_debugger_break();
510
511 for (timeout = 100000000; timeout != 0; --timeout) {
512 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
513 break;
514 barrier();
515 }
516 }
517 remove_bpts();
518 disable_surveillance();
519
520 if (bp || TRAP(regs) == 0xd00)
521 ppc_inst_dump(regs->nip, 1, 0);
522 printf("enter ? for help\n");
523 mb();
524 xmon_gate = 1;
525 barrier();
526 }
527
528 cmdloop:
529 while (in_xmon) {
530 if (secondary) {
531 if (cpu == xmon_owner) {
532 if (!test_and_set_bit(0, &xmon_taken)) {
533 secondary = 0;
534 continue;
535 }
536
537 while (cpu == xmon_owner)
538 barrier();
539 }
540 barrier();
541 } else {
542 cmd = cmds(regs);
543 if (cmd != 0) {
544
545 insert_bpts();
546 xmon_gate = 0;
547 wmb();
548 in_xmon = 0;
549 break;
550 }
551
552 secondary = 1;
553 }
554 }
555 leave:
556 cpumask_clear_cpu(cpu, &cpus_in_xmon);
557 xmon_fault_jmp[cpu] = NULL;
558#else
559
560 if (in_xmon) {
561 printf("Exception %lx %s in xmon, returning to main loop\n",
562 regs->trap, getvecname(TRAP(regs)));
563 longjmp(xmon_fault_jmp[0], 1);
564 }
565 if (setjmp(recurse_jmp) == 0) {
566 xmon_fault_jmp[0] = recurse_jmp;
567 in_xmon = 1;
568
569 excprint(regs);
570 bp = at_breakpoint(regs->nip);
571 if (bp) {
572 printf("Stopped at breakpoint %lx (", BP_NUM(bp));
573 xmon_print_symbol(regs->nip, " ", ")\n");
574 }
575 if (unrecoverable_excp(regs))
576 printf("WARNING: exception is not recoverable, "
577 "can't continue\n");
578 remove_bpts();
579 disable_surveillance();
580
581 if (bp || TRAP(regs) == 0xd00)
582 ppc_inst_dump(regs->nip, 1, 0);
583 printf("enter ? for help\n");
584 }
585
586 cmd = cmds(regs);
587
588 insert_bpts();
589 in_xmon = 0;
590#endif
591
592#ifdef CONFIG_BOOKE
593 if (regs->msr & MSR_DE) {
594 bp = at_breakpoint(regs->nip);
595 if (bp != NULL) {
596 regs->nip = (unsigned long) &bp->instr[0];
597 atomic_inc(&bp->ref_count);
598 }
599 }
600#else
601 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
602 bp = at_breakpoint(regs->nip);
603 if (bp != NULL) {
604 int stepped = emulate_step(regs, bp->instr[0]);
605 if (stepped == 0) {
606 regs->nip = (unsigned long) &bp->instr[0];
607 atomic_inc(&bp->ref_count);
608 } else if (stepped < 0) {
609 printf("Couldn't single-step %s instruction\n",
610 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
611 }
612 }
613 }
614#endif
615 insert_cpu_bpts();
616
617 touch_nmi_watchdog();
618 local_irq_restore(flags);
619
620 return cmd != 'X' && cmd != EOF;
621}
622
623int xmon(struct pt_regs *excp)
624{
625 struct pt_regs regs;
626
627 if (excp == NULL) {
628 ppc_save_regs(®s);
629 excp = ®s;
630 }
631
632 return xmon_core(excp, 0);
633}
634EXPORT_SYMBOL(xmon);
635
636irqreturn_t xmon_irq(int irq, void *d)
637{
638 unsigned long flags;
639 local_irq_save(flags);
640 printf("Keyboard interrupt\n");
641 xmon(get_irq_regs());
642 local_irq_restore(flags);
643 return IRQ_HANDLED;
644}
645
646static int xmon_bpt(struct pt_regs *regs)
647{
648 struct bpt *bp;
649 unsigned long offset;
650
651 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
652 return 0;
653
654
655 bp = in_breakpoint_table(regs->nip, &offset);
656 if (bp != NULL && offset == 4) {
657 regs->nip = bp->address + 4;
658 atomic_dec(&bp->ref_count);
659 return 1;
660 }
661
662
663 bp = at_breakpoint(regs->nip);
664 if (!bp)
665 return 0;
666
667 xmon_core(regs, 0);
668
669 return 1;
670}
671
672static int xmon_sstep(struct pt_regs *regs)
673{
674 if (user_mode(regs))
675 return 0;
676 xmon_core(regs, 0);
677 return 1;
678}
679
680static int xmon_break_match(struct pt_regs *regs)
681{
682 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
683 return 0;
684 if (dabr.enabled == 0)
685 return 0;
686 xmon_core(regs, 0);
687 return 1;
688}
689
690static int xmon_iabr_match(struct pt_regs *regs)
691{
692 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
693 return 0;
694 if (iabr == NULL)
695 return 0;
696 xmon_core(regs, 0);
697 return 1;
698}
699
700static int xmon_ipi(struct pt_regs *regs)
701{
702#ifdef CONFIG_SMP
703 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
704 xmon_core(regs, 1);
705#endif
706 return 0;
707}
708
709static int xmon_fault_handler(struct pt_regs *regs)
710{
711 struct bpt *bp;
712 unsigned long offset;
713
714 if (in_xmon && catch_memory_errors)
715 handle_fault(regs);
716
717 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
718 bp = in_breakpoint_table(regs->nip, &offset);
719 if (bp != NULL) {
720 regs->nip = bp->address + offset;
721 atomic_dec(&bp->ref_count);
722 }
723 }
724
725 return 0;
726}
727
728static struct bpt *at_breakpoint(unsigned long pc)
729{
730 int i;
731 struct bpt *bp;
732
733 bp = bpts;
734 for (i = 0; i < NBPTS; ++i, ++bp)
735 if (bp->enabled && pc == bp->address)
736 return bp;
737 return NULL;
738}
739
740static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
741{
742 unsigned long off;
743
744 off = nip - (unsigned long) bpts;
745 if (off >= sizeof(bpts))
746 return NULL;
747 off %= sizeof(struct bpt);
748 if (off != offsetof(struct bpt, instr[0])
749 && off != offsetof(struct bpt, instr[1]))
750 return NULL;
751 *offp = off - offsetof(struct bpt, instr[0]);
752 return (struct bpt *) (nip - off);
753}
754
755static struct bpt *new_breakpoint(unsigned long a)
756{
757 struct bpt *bp;
758
759 a &= ~3UL;
760 bp = at_breakpoint(a);
761 if (bp)
762 return bp;
763
764 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
765 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
766 bp->address = a;
767 bp->instr[1] = bpinstr;
768 store_inst(&bp->instr[1]);
769 return bp;
770 }
771 }
772
773 printf("Sorry, no free breakpoints. Please clear one first.\n");
774 return NULL;
775}
776
777static void insert_bpts(void)
778{
779 int i;
780 struct bpt *bp;
781
782 bp = bpts;
783 for (i = 0; i < NBPTS; ++i, ++bp) {
784 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
785 continue;
786 if (mread(bp->address, &bp->instr[0], 4) != 4) {
787 printf("Couldn't read instruction at %lx, "
788 "disabling breakpoint there\n", bp->address);
789 bp->enabled = 0;
790 continue;
791 }
792 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
793 printf("Breakpoint at %lx is on an mtmsrd or rfid "
794 "instruction, disabling it\n", bp->address);
795 bp->enabled = 0;
796 continue;
797 }
798 store_inst(&bp->instr[0]);
799 if (bp->enabled & BP_CIABR)
800 continue;
801 if (mwrite(bp->address, &bpinstr, 4) != 4) {
802 printf("Couldn't write instruction at %lx, "
803 "disabling breakpoint there\n", bp->address);
804 bp->enabled &= ~BP_TRAP;
805 continue;
806 }
807 store_inst((void *)bp->address);
808 }
809}
810
811static void insert_cpu_bpts(void)
812{
813 struct arch_hw_breakpoint brk;
814
815 if (dabr.enabled) {
816 brk.address = dabr.address;
817 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
818 brk.len = 8;
819 __set_breakpoint(&brk);
820 }
821
822 if (iabr)
823 set_ciabr(iabr->address);
824}
825
826static void remove_bpts(void)
827{
828 int i;
829 struct bpt *bp;
830 unsigned instr;
831
832 bp = bpts;
833 for (i = 0; i < NBPTS; ++i, ++bp) {
834 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
835 continue;
836 if (mread(bp->address, &instr, 4) == 4
837 && instr == bpinstr
838 && mwrite(bp->address, &bp->instr, 4) != 4)
839 printf("Couldn't remove breakpoint at %lx\n",
840 bp->address);
841 else
842 store_inst((void *)bp->address);
843 }
844}
845
846static void remove_cpu_bpts(void)
847{
848 hw_breakpoint_disable();
849 write_ciabr(0);
850}
851
852static void set_lpp_cmd(void)
853{
854 unsigned long lpp;
855
856 if (!scanhex(&lpp)) {
857 printf("Invalid number.\n");
858 lpp = 0;
859 }
860 xmon_set_pagination_lpp(lpp);
861}
862
863static char *last_cmd;
864
865static int
866cmds(struct pt_regs *excp)
867{
868 int cmd = 0;
869
870 last_cmd = NULL;
871 xmon_regs = excp;
872
873 if (!xmon_no_auto_backtrace) {
874 xmon_no_auto_backtrace = 1;
875 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
876 }
877
878 for(;;) {
879#ifdef CONFIG_SMP
880 printf("%x:", smp_processor_id());
881#endif
882 printf("mon> ");
883 flush_input();
884 termch = 0;
885 cmd = skipbl();
886 if( cmd == '\n' ) {
887 if (last_cmd == NULL)
888 continue;
889 take_input(last_cmd);
890 last_cmd = NULL;
891 cmd = inchar();
892 }
893 switch (cmd) {
894 case 'm':
895 cmd = inchar();
896 switch (cmd) {
897 case 'm':
898 case 's':
899 case 'd':
900 memops(cmd);
901 break;
902 case 'l':
903 memlocate();
904 break;
905 case 'z':
906 memzcan();
907 break;
908 case 'i':
909 show_mem(0);
910 break;
911 default:
912 termch = cmd;
913 memex();
914 }
915 break;
916 case 'd':
917 dump();
918 break;
919 case 'l':
920 symbol_lookup();
921 break;
922 case 'r':
923 prregs(excp);
924 break;
925 case 'e':
926 excprint(excp);
927 break;
928 case 'S':
929 super_regs();
930 break;
931 case 't':
932 backtrace(excp);
933 break;
934 case 'f':
935 cacheflush();
936 break;
937 case 's':
938 if (do_spu_cmd() == 0)
939 break;
940 if (do_step(excp))
941 return cmd;
942 break;
943 case 'x':
944 case 'X':
945 return cmd;
946 case EOF:
947 printf(" <no input ...>\n");
948 mdelay(2000);
949 return cmd;
950 case '?':
951 xmon_puts(help_string);
952 break;
953 case '#':
954 set_lpp_cmd();
955 break;
956 case 'b':
957 bpt_cmds();
958 break;
959 case 'C':
960 csum();
961 break;
962 case 'c':
963 if (cpu_cmd())
964 return 0;
965 break;
966 case 'z':
967 bootcmds();
968 break;
969 case 'p':
970 proccall();
971 break;
972 case 'P':
973 show_tasks();
974 break;
975#ifdef CONFIG_PPC_STD_MMU
976 case 'u':
977 dump_segments();
978 break;
979#elif defined(CONFIG_44x)
980 case 'u':
981 dump_tlb_44x();
982 break;
983#elif defined(CONFIG_PPC_BOOK3E)
984 case 'u':
985 dump_tlb_book3e();
986 break;
987#endif
988 default:
989 printf("Unrecognized command: ");
990 do {
991 if (' ' < cmd && cmd <= '~')
992 putchar(cmd);
993 else
994 printf("\\x%x", cmd);
995 cmd = inchar();
996 } while (cmd != '\n');
997 printf(" (type ? for help)\n");
998 break;
999 }
1000 }
1001}
1002
1003#ifdef CONFIG_BOOKE
1004static int do_step(struct pt_regs *regs)
1005{
1006 regs->msr |= MSR_DE;
1007 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1008 return 1;
1009}
1010#else
1011
1012
1013
1014
1015static int do_step(struct pt_regs *regs)
1016{
1017 unsigned int instr;
1018 int stepped;
1019
1020
1021 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1022 if (mread(regs->nip, &instr, 4) == 4) {
1023 stepped = emulate_step(regs, instr);
1024 if (stepped < 0) {
1025 printf("Couldn't single-step %s instruction\n",
1026 (IS_RFID(instr)? "rfid": "mtmsrd"));
1027 return 0;
1028 }
1029 if (stepped > 0) {
1030 regs->trap = 0xd00 | (regs->trap & 1);
1031 printf("stepped to ");
1032 xmon_print_symbol(regs->nip, " ", "\n");
1033 ppc_inst_dump(regs->nip, 1, 0);
1034 return 0;
1035 }
1036 }
1037 }
1038 regs->msr |= MSR_SE;
1039 return 1;
1040}
1041#endif
1042
1043static void bootcmds(void)
1044{
1045 int cmd;
1046
1047 cmd = inchar();
1048 if (cmd == 'r')
1049 ppc_md.restart(NULL);
1050 else if (cmd == 'h')
1051 ppc_md.halt();
1052 else if (cmd == 'p')
1053 if (pm_power_off)
1054 pm_power_off();
1055}
1056
1057static int cpu_cmd(void)
1058{
1059#ifdef CONFIG_SMP
1060 unsigned long cpu, first_cpu, last_cpu;
1061 int timeout;
1062
1063 if (!scanhex(&cpu)) {
1064
1065 printf("cpus stopped:");
1066 last_cpu = first_cpu = NR_CPUS;
1067 for_each_possible_cpu(cpu) {
1068 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1069 if (cpu == last_cpu + 1) {
1070 last_cpu = cpu;
1071 } else {
1072 if (last_cpu != first_cpu)
1073 printf("-0x%lx", last_cpu);
1074 last_cpu = first_cpu = cpu;
1075 printf(" 0x%lx", cpu);
1076 }
1077 }
1078 }
1079 if (last_cpu != first_cpu)
1080 printf("-0x%lx", last_cpu);
1081 printf("\n");
1082 return 0;
1083 }
1084
1085 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1086 printf("cpu 0x%x isn't in xmon\n", cpu);
1087 return 0;
1088 }
1089 xmon_taken = 0;
1090 mb();
1091 xmon_owner = cpu;
1092 timeout = 10000000;
1093 while (!xmon_taken) {
1094 if (--timeout == 0) {
1095 if (test_and_set_bit(0, &xmon_taken))
1096 break;
1097
1098 mb();
1099 xmon_owner = smp_processor_id();
1100 printf("cpu 0x%x didn't take control\n", cpu);
1101 return 0;
1102 }
1103 barrier();
1104 }
1105 return 1;
1106#else
1107 return 0;
1108#endif
1109}
1110
1111static unsigned short fcstab[256] = {
1112 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1113 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1114 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1115 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1116 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1117 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1118 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1119 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1120 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1121 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1122 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1123 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1124 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1125 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1126 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1127 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1128 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1129 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1130 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1131 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1132 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1133 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1134 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1135 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1136 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1137 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1138 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1139 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1140 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1141 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1142 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1143 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1144};
1145
1146#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1147
1148static void
1149csum(void)
1150{
1151 unsigned int i;
1152 unsigned short fcs;
1153 unsigned char v;
1154
1155 if (!scanhex(&adrs))
1156 return;
1157 if (!scanhex(&ncsum))
1158 return;
1159 fcs = 0xffff;
1160 for (i = 0; i < ncsum; ++i) {
1161 if (mread(adrs+i, &v, 1) == 0) {
1162 printf("csum stopped at "REG"\n", adrs+i);
1163 break;
1164 }
1165 fcs = FCS(fcs, v);
1166 }
1167 printf("%x\n", fcs);
1168}
1169
1170
1171
1172
1173static long check_bp_loc(unsigned long addr)
1174{
1175 unsigned int instr;
1176
1177 addr &= ~3;
1178 if (!is_kernel_addr(addr)) {
1179 printf("Breakpoints may only be placed at kernel addresses\n");
1180 return 0;
1181 }
1182 if (!mread(addr, &instr, sizeof(instr))) {
1183 printf("Can't read instruction at address %lx\n", addr);
1184 return 0;
1185 }
1186 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1187 printf("Breakpoints may not be placed on mtmsrd or rfid "
1188 "instructions\n");
1189 return 0;
1190 }
1191 return 1;
1192}
1193
1194static char *breakpoint_help_string =
1195 "Breakpoint command usage:\n"
1196 "b show breakpoints\n"
1197 "b <addr> [cnt] set breakpoint at given instr addr\n"
1198 "bc clear all breakpoints\n"
1199 "bc <n/addr> clear breakpoint number n or at addr\n"
1200 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1201 "bd <addr> [cnt] set hardware data breakpoint\n"
1202 "";
1203
1204static void
1205bpt_cmds(void)
1206{
1207 int cmd;
1208 unsigned long a;
1209 int mode, i;
1210 struct bpt *bp;
1211 const char badaddr[] = "Only kernel addresses are permitted "
1212 "for breakpoints\n";
1213
1214 cmd = inchar();
1215 switch (cmd) {
1216#ifndef CONFIG_8xx
1217 case 'd':
1218 mode = 7;
1219 cmd = inchar();
1220 if (cmd == 'r')
1221 mode = 5;
1222 else if (cmd == 'w')
1223 mode = 6;
1224 else
1225 termch = cmd;
1226 dabr.address = 0;
1227 dabr.enabled = 0;
1228 if (scanhex(&dabr.address)) {
1229 if (!is_kernel_addr(dabr.address)) {
1230 printf(badaddr);
1231 break;
1232 }
1233 dabr.address &= ~HW_BRK_TYPE_DABR;
1234 dabr.enabled = mode | BP_DABR;
1235 }
1236 break;
1237
1238 case 'i':
1239 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1240 printf("Hardware instruction breakpoint "
1241 "not supported on this cpu\n");
1242 break;
1243 }
1244 if (iabr) {
1245 iabr->enabled &= ~BP_CIABR;
1246 iabr = NULL;
1247 }
1248 if (!scanhex(&a))
1249 break;
1250 if (!check_bp_loc(a))
1251 break;
1252 bp = new_breakpoint(a);
1253 if (bp != NULL) {
1254 bp->enabled |= BP_CIABR;
1255 iabr = bp;
1256 }
1257 break;
1258#endif
1259
1260 case 'c':
1261 if (!scanhex(&a)) {
1262
1263 for (i = 0; i < NBPTS; ++i)
1264 bpts[i].enabled = 0;
1265 iabr = NULL;
1266 dabr.enabled = 0;
1267 printf("All breakpoints cleared\n");
1268 break;
1269 }
1270
1271 if (a <= NBPTS && a >= 1) {
1272
1273 bp = &bpts[a-1];
1274 } else {
1275
1276 bp = at_breakpoint(a);
1277 if (bp == NULL) {
1278 printf("No breakpoint at %lx\n", a);
1279 break;
1280 }
1281 }
1282
1283 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1284 xmon_print_symbol(bp->address, " ", ")\n");
1285 bp->enabled = 0;
1286 break;
1287
1288 default:
1289 termch = cmd;
1290 cmd = skipbl();
1291 if (cmd == '?') {
1292 printf(breakpoint_help_string);
1293 break;
1294 }
1295 termch = cmd;
1296 if (!scanhex(&a)) {
1297
1298 printf(" type address\n");
1299 if (dabr.enabled) {
1300 printf(" data "REG" [", dabr.address);
1301 if (dabr.enabled & 1)
1302 printf("r");
1303 if (dabr.enabled & 2)
1304 printf("w");
1305 printf("]\n");
1306 }
1307 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1308 if (!bp->enabled)
1309 continue;
1310 printf("%2x %s ", BP_NUM(bp),
1311 (bp->enabled & BP_CIABR) ? "inst": "trap");
1312 xmon_print_symbol(bp->address, " ", "\n");
1313 }
1314 break;
1315 }
1316
1317 if (!check_bp_loc(a))
1318 break;
1319 bp = new_breakpoint(a);
1320 if (bp != NULL)
1321 bp->enabled |= BP_TRAP;
1322 break;
1323 }
1324}
1325
1326
1327static
1328const char *getvecname(unsigned long vec)
1329{
1330 char *ret;
1331
1332 switch (vec) {
1333 case 0x100: ret = "(System Reset)"; break;
1334 case 0x200: ret = "(Machine Check)"; break;
1335 case 0x300: ret = "(Data Access)"; break;
1336 case 0x380: ret = "(Data SLB Access)"; break;
1337 case 0x400: ret = "(Instruction Access)"; break;
1338 case 0x480: ret = "(Instruction SLB Access)"; break;
1339 case 0x500: ret = "(Hardware Interrupt)"; break;
1340 case 0x600: ret = "(Alignment)"; break;
1341 case 0x700: ret = "(Program Check)"; break;
1342 case 0x800: ret = "(FPU Unavailable)"; break;
1343 case 0x900: ret = "(Decrementer)"; break;
1344 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1345 case 0xa00: ret = "(Doorbell)"; break;
1346 case 0xc00: ret = "(System Call)"; break;
1347 case 0xd00: ret = "(Single Step)"; break;
1348 case 0xe40: ret = "(Emulation Assist)"; break;
1349 case 0xe60: ret = "(HMI)"; break;
1350 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1351 case 0xf00: ret = "(Performance Monitor)"; break;
1352 case 0xf20: ret = "(Altivec Unavailable)"; break;
1353 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1354 case 0x1500: ret = "(Denormalisation)"; break;
1355 case 0x1700: ret = "(Altivec Assist)"; break;
1356 default: ret = "";
1357 }
1358 return ret;
1359}
1360
1361static void get_function_bounds(unsigned long pc, unsigned long *startp,
1362 unsigned long *endp)
1363{
1364 unsigned long size, offset;
1365 const char *name;
1366
1367 *startp = *endp = 0;
1368 if (pc == 0)
1369 return;
1370 if (setjmp(bus_error_jmp) == 0) {
1371 catch_memory_errors = 1;
1372 sync();
1373 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1374 if (name != NULL) {
1375 *startp = pc - offset;
1376 *endp = pc - offset + size;
1377 }
1378 sync();
1379 }
1380 catch_memory_errors = 0;
1381}
1382
1383#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1384#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1385
1386static void xmon_show_stack(unsigned long sp, unsigned long lr,
1387 unsigned long pc)
1388{
1389 int max_to_print = 64;
1390 unsigned long ip;
1391 unsigned long newsp;
1392 unsigned long marker;
1393 struct pt_regs regs;
1394
1395 while (max_to_print--) {
1396 if (sp < PAGE_OFFSET) {
1397 if (sp != 0)
1398 printf("SP (%lx) is in userspace\n", sp);
1399 break;
1400 }
1401
1402 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1403 || !mread(sp, &newsp, sizeof(unsigned long))) {
1404 printf("Couldn't read stack frame at %lx\n", sp);
1405 break;
1406 }
1407
1408
1409
1410
1411
1412
1413 if ((pc | lr) != 0) {
1414 unsigned long fnstart, fnend;
1415 unsigned long nextip;
1416 int printip = 1;
1417
1418 get_function_bounds(pc, &fnstart, &fnend);
1419 nextip = 0;
1420 if (newsp > sp)
1421 mread(newsp + LRSAVE_OFFSET, &nextip,
1422 sizeof(unsigned long));
1423 if (lr == ip) {
1424 if (lr < PAGE_OFFSET
1425 || (fnstart <= lr && lr < fnend))
1426 printip = 0;
1427 } else if (lr == nextip) {
1428 printip = 0;
1429 } else if (lr >= PAGE_OFFSET
1430 && !(fnstart <= lr && lr < fnend)) {
1431 printf("[link register ] ");
1432 xmon_print_symbol(lr, " ", "\n");
1433 }
1434 if (printip) {
1435 printf("["REG"] ", sp);
1436 xmon_print_symbol(ip, " ", " (unreliable)\n");
1437 }
1438 pc = lr = 0;
1439
1440 } else {
1441 printf("["REG"] ", sp);
1442 xmon_print_symbol(ip, " ", "\n");
1443 }
1444
1445
1446
1447 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1448 && marker == STACK_FRAME_REGS_MARKER) {
1449 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1450 != sizeof(regs)) {
1451 printf("Couldn't read registers at %lx\n",
1452 sp + STACK_FRAME_OVERHEAD);
1453 break;
1454 }
1455 printf("--- Exception: %lx %s at ", regs.trap,
1456 getvecname(TRAP(®s)));
1457 pc = regs.nip;
1458 lr = regs.link;
1459 xmon_print_symbol(pc, " ", "\n");
1460 }
1461
1462 if (newsp == 0)
1463 break;
1464
1465 sp = newsp;
1466 }
1467}
1468
1469static void backtrace(struct pt_regs *excp)
1470{
1471 unsigned long sp;
1472
1473 if (scanhex(&sp))
1474 xmon_show_stack(sp, 0, 0);
1475 else
1476 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1477 scannl();
1478}
1479
1480static void print_bug_trap(struct pt_regs *regs)
1481{
1482#ifdef CONFIG_BUG
1483 const struct bug_entry *bug;
1484 unsigned long addr;
1485
1486 if (regs->msr & MSR_PR)
1487 return;
1488 addr = regs->nip;
1489 if (addr < PAGE_OFFSET)
1490 return;
1491 bug = find_bug(regs->nip);
1492 if (bug == NULL)
1493 return;
1494 if (is_warning_bug(bug))
1495 return;
1496
1497#ifdef CONFIG_DEBUG_BUGVERBOSE
1498 printf("kernel BUG at %s:%u!\n",
1499 bug->file, bug->line);
1500#else
1501 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1502#endif
1503#endif
1504}
1505
1506static void excprint(struct pt_regs *fp)
1507{
1508 unsigned long trap;
1509
1510#ifdef CONFIG_SMP
1511 printf("cpu 0x%x: ", smp_processor_id());
1512#endif
1513
1514 trap = TRAP(fp);
1515 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1516 printf(" pc: ");
1517 xmon_print_symbol(fp->nip, ": ", "\n");
1518
1519 printf(" lr: ", fp->link);
1520 xmon_print_symbol(fp->link, ": ", "\n");
1521
1522 printf(" sp: %lx\n", fp->gpr[1]);
1523 printf(" msr: %lx\n", fp->msr);
1524
1525 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1526 printf(" dar: %lx\n", fp->dar);
1527 if (trap != 0x380)
1528 printf(" dsisr: %lx\n", fp->dsisr);
1529 }
1530
1531 printf(" current = 0x%lx\n", current);
1532#ifdef CONFIG_PPC64
1533 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1534 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1535#endif
1536 if (current) {
1537 printf(" pid = %ld, comm = %s\n",
1538 current->pid, current->comm);
1539 }
1540
1541 if (trap == 0x700)
1542 print_bug_trap(fp);
1543
1544 printf(linux_banner);
1545}
1546
1547static void prregs(struct pt_regs *fp)
1548{
1549 int n, trap;
1550 unsigned long base;
1551 struct pt_regs regs;
1552
1553 if (scanhex(&base)) {
1554 if (setjmp(bus_error_jmp) == 0) {
1555 catch_memory_errors = 1;
1556 sync();
1557 regs = *(struct pt_regs *)base;
1558 sync();
1559 __delay(200);
1560 } else {
1561 catch_memory_errors = 0;
1562 printf("*** Error reading registers from "REG"\n",
1563 base);
1564 return;
1565 }
1566 catch_memory_errors = 0;
1567 fp = ®s;
1568 }
1569
1570#ifdef CONFIG_PPC64
1571 if (FULL_REGS(fp)) {
1572 for (n = 0; n < 16; ++n)
1573 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1574 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1575 } else {
1576 for (n = 0; n < 7; ++n)
1577 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1578 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1579 }
1580#else
1581 for (n = 0; n < 32; ++n) {
1582 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1583 (n & 3) == 3? "\n": " ");
1584 if (n == 12 && !FULL_REGS(fp)) {
1585 printf("\n");
1586 break;
1587 }
1588 }
1589#endif
1590 printf("pc = ");
1591 xmon_print_symbol(fp->nip, " ", "\n");
1592 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1593 printf("cfar= ");
1594 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1595 }
1596 printf("lr = ");
1597 xmon_print_symbol(fp->link, " ", "\n");
1598 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1599 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1600 fp->ctr, fp->xer, fp->trap);
1601 trap = TRAP(fp);
1602 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1603 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1604}
1605
1606static void cacheflush(void)
1607{
1608 int cmd;
1609 unsigned long nflush;
1610
1611 cmd = inchar();
1612 if (cmd != 'i')
1613 termch = cmd;
1614 scanhex((void *)&adrs);
1615 if (termch != '\n')
1616 termch = 0;
1617 nflush = 1;
1618 scanhex(&nflush);
1619 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1620 if (setjmp(bus_error_jmp) == 0) {
1621 catch_memory_errors = 1;
1622 sync();
1623
1624 if (cmd != 'i') {
1625 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1626 cflush((void *) adrs);
1627 } else {
1628 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1629 cinval((void *) adrs);
1630 }
1631 sync();
1632
1633 __delay(200);
1634 }
1635 catch_memory_errors = 0;
1636}
1637
1638static unsigned long
1639read_spr(int n)
1640{
1641 unsigned int instrs[2];
1642 unsigned long (*code)(void);
1643 unsigned long ret = -1UL;
1644#ifdef CONFIG_PPC64
1645 unsigned long opd[3];
1646
1647 opd[0] = (unsigned long)instrs;
1648 opd[1] = 0;
1649 opd[2] = 0;
1650 code = (unsigned long (*)(void)) opd;
1651#else
1652 code = (unsigned long (*)(void)) instrs;
1653#endif
1654
1655
1656 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1657 instrs[1] = 0x4e800020;
1658 store_inst(instrs);
1659 store_inst(instrs+1);
1660
1661 if (setjmp(bus_error_jmp) == 0) {
1662 catch_memory_errors = 1;
1663 sync();
1664
1665 ret = code();
1666
1667 sync();
1668
1669 __delay(200);
1670 n = size;
1671 }
1672
1673 return ret;
1674}
1675
1676static void
1677write_spr(int n, unsigned long val)
1678{
1679 unsigned int instrs[2];
1680 unsigned long (*code)(unsigned long);
1681#ifdef CONFIG_PPC64
1682 unsigned long opd[3];
1683
1684 opd[0] = (unsigned long)instrs;
1685 opd[1] = 0;
1686 opd[2] = 0;
1687 code = (unsigned long (*)(unsigned long)) opd;
1688#else
1689 code = (unsigned long (*)(unsigned long)) instrs;
1690#endif
1691
1692 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1693 instrs[1] = 0x4e800020;
1694 store_inst(instrs);
1695 store_inst(instrs+1);
1696
1697 if (setjmp(bus_error_jmp) == 0) {
1698 catch_memory_errors = 1;
1699 sync();
1700
1701 code(val);
1702
1703 sync();
1704
1705 __delay(200);
1706 n = size;
1707 }
1708}
1709
1710static unsigned long regno;
1711extern char exc_prolog;
1712extern char dec_exc;
1713
1714static void super_regs(void)
1715{
1716 int cmd;
1717 unsigned long val;
1718
1719 cmd = skipbl();
1720 if (cmd == '\n') {
1721 unsigned long sp, toc;
1722 asm("mr %0,1" : "=r" (sp) :);
1723 asm("mr %0,2" : "=r" (toc) :);
1724
1725 printf("msr = "REG" sprg0= "REG"\n",
1726 mfmsr(), mfspr(SPRN_SPRG0));
1727 printf("pvr = "REG" sprg1= "REG"\n",
1728 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1729 printf("dec = "REG" sprg2= "REG"\n",
1730 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1731 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1732 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1733
1734 return;
1735 }
1736
1737 scanhex(®no);
1738 switch (cmd) {
1739 case 'w':
1740 val = read_spr(regno);
1741 scanhex(&val);
1742 write_spr(regno, val);
1743
1744 case 'r':
1745 printf("spr %lx = %lx\n", regno, read_spr(regno));
1746 break;
1747 }
1748 scannl();
1749}
1750
1751
1752
1753
1754static int
1755mread(unsigned long adrs, void *buf, int size)
1756{
1757 volatile int n;
1758 char *p, *q;
1759
1760 n = 0;
1761 if (setjmp(bus_error_jmp) == 0) {
1762 catch_memory_errors = 1;
1763 sync();
1764 p = (char *)adrs;
1765 q = (char *)buf;
1766 switch (size) {
1767 case 2:
1768 *(u16 *)q = *(u16 *)p;
1769 break;
1770 case 4:
1771 *(u32 *)q = *(u32 *)p;
1772 break;
1773 case 8:
1774 *(u64 *)q = *(u64 *)p;
1775 break;
1776 default:
1777 for( ; n < size; ++n) {
1778 *q++ = *p++;
1779 sync();
1780 }
1781 }
1782 sync();
1783
1784 __delay(200);
1785 n = size;
1786 }
1787 catch_memory_errors = 0;
1788 return n;
1789}
1790
1791static int
1792mwrite(unsigned long adrs, void *buf, int size)
1793{
1794 volatile int n;
1795 char *p, *q;
1796
1797 n = 0;
1798 if (setjmp(bus_error_jmp) == 0) {
1799 catch_memory_errors = 1;
1800 sync();
1801 p = (char *) adrs;
1802 q = (char *) buf;
1803 switch (size) {
1804 case 2:
1805 *(u16 *)p = *(u16 *)q;
1806 break;
1807 case 4:
1808 *(u32 *)p = *(u32 *)q;
1809 break;
1810 case 8:
1811 *(u64 *)p = *(u64 *)q;
1812 break;
1813 default:
1814 for ( ; n < size; ++n) {
1815 *p++ = *q++;
1816 sync();
1817 }
1818 }
1819 sync();
1820
1821 __delay(200);
1822 n = size;
1823 } else {
1824 printf("*** Error writing address "REG"\n", adrs + n);
1825 }
1826 catch_memory_errors = 0;
1827 return n;
1828}
1829
1830static int fault_type;
1831static int fault_except;
1832static char *fault_chars[] = { "--", "**", "##" };
1833
1834static int handle_fault(struct pt_regs *regs)
1835{
1836 fault_except = TRAP(regs);
1837 switch (TRAP(regs)) {
1838 case 0x200:
1839 fault_type = 0;
1840 break;
1841 case 0x300:
1842 case 0x380:
1843 fault_type = 1;
1844 break;
1845 default:
1846 fault_type = 2;
1847 }
1848
1849 longjmp(bus_error_jmp, 1);
1850
1851 return 0;
1852}
1853
1854#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1855
1856static void
1857byterev(unsigned char *val, int size)
1858{
1859 int t;
1860
1861 switch (size) {
1862 case 2:
1863 SWAP(val[0], val[1], t);
1864 break;
1865 case 4:
1866 SWAP(val[0], val[3], t);
1867 SWAP(val[1], val[2], t);
1868 break;
1869 case 8:
1870 SWAP(val[0], val[7], t);
1871 SWAP(val[1], val[6], t);
1872 SWAP(val[2], val[5], t);
1873 SWAP(val[3], val[4], t);
1874 break;
1875 }
1876}
1877
1878static int brev;
1879static int mnoread;
1880
1881static char *memex_help_string =
1882 "Memory examine command usage:\n"
1883 "m [addr] [flags] examine/change memory\n"
1884 " addr is optional. will start where left off.\n"
1885 " flags may include chars from this set:\n"
1886 " b modify by bytes (default)\n"
1887 " w modify by words (2 byte)\n"
1888 " l modify by longs (4 byte)\n"
1889 " d modify by doubleword (8 byte)\n"
1890 " r toggle reverse byte order mode\n"
1891 " n do not read memory (for i/o spaces)\n"
1892 " . ok to read (default)\n"
1893 "NOTE: flags are saved as defaults\n"
1894 "";
1895
1896static char *memex_subcmd_help_string =
1897 "Memory examine subcommands:\n"
1898 " hexval write this val to current location\n"
1899 " 'string' write chars from string to this location\n"
1900 " ' increment address\n"
1901 " ^ decrement address\n"
1902 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1903 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1904 " ` clear no-read flag\n"
1905 " ; stay at this addr\n"
1906 " v change to byte mode\n"
1907 " w change to word (2 byte) mode\n"
1908 " l change to long (4 byte) mode\n"
1909 " u change to doubleword (8 byte) mode\n"
1910 " m addr change current addr\n"
1911 " n toggle no-read flag\n"
1912 " r toggle byte reverse flag\n"
1913 " < count back up count bytes\n"
1914 " > count skip forward count bytes\n"
1915 " x exit this mode\n"
1916 "";
1917
1918static void
1919memex(void)
1920{
1921 int cmd, inc, i, nslash;
1922 unsigned long n;
1923 unsigned char val[16];
1924
1925 scanhex((void *)&adrs);
1926 cmd = skipbl();
1927 if (cmd == '?') {
1928 printf(memex_help_string);
1929 return;
1930 } else {
1931 termch = cmd;
1932 }
1933 last_cmd = "m\n";
1934 while ((cmd = skipbl()) != '\n') {
1935 switch( cmd ){
1936 case 'b': size = 1; break;
1937 case 'w': size = 2; break;
1938 case 'l': size = 4; break;
1939 case 'd': size = 8; break;
1940 case 'r': brev = !brev; break;
1941 case 'n': mnoread = 1; break;
1942 case '.': mnoread = 0; break;
1943 }
1944 }
1945 if( size <= 0 )
1946 size = 1;
1947 else if( size > 8 )
1948 size = 8;
1949 for(;;){
1950 if (!mnoread)
1951 n = mread(adrs, val, size);
1952 printf(REG"%c", adrs, brev? 'r': ' ');
1953 if (!mnoread) {
1954 if (brev)
1955 byterev(val, size);
1956 putchar(' ');
1957 for (i = 0; i < n; ++i)
1958 printf("%.2x", val[i]);
1959 for (; i < size; ++i)
1960 printf("%s", fault_chars[fault_type]);
1961 }
1962 putchar(' ');
1963 inc = size;
1964 nslash = 0;
1965 for(;;){
1966 if( scanhex(&n) ){
1967 for (i = 0; i < size; ++i)
1968 val[i] = n >> (i * 8);
1969 if (!brev)
1970 byterev(val, size);
1971 mwrite(adrs, val, size);
1972 inc = size;
1973 }
1974 cmd = skipbl();
1975 if (cmd == '\n')
1976 break;
1977 inc = 0;
1978 switch (cmd) {
1979 case '\'':
1980 for(;;){
1981 n = inchar();
1982 if( n == '\\' )
1983 n = bsesc();
1984 else if( n == '\'' )
1985 break;
1986 for (i = 0; i < size; ++i)
1987 val[i] = n >> (i * 8);
1988 if (!brev)
1989 byterev(val, size);
1990 mwrite(adrs, val, size);
1991 adrs += size;
1992 }
1993 adrs -= size;
1994 inc = size;
1995 break;
1996 case ',':
1997 adrs += size;
1998 break;
1999 case '.':
2000 mnoread = 0;
2001 break;
2002 case ';':
2003 break;
2004 case 'x':
2005 case EOF:
2006 scannl();
2007 return;
2008 case 'b':
2009 case 'v':
2010 size = 1;
2011 break;
2012 case 'w':
2013 size = 2;
2014 break;
2015 case 'l':
2016 size = 4;
2017 break;
2018 case 'u':
2019 size = 8;
2020 break;
2021 case '^':
2022 adrs -= size;
2023 break;
2024 case '/':
2025 if (nslash > 0)
2026 adrs -= 1 << nslash;
2027 else
2028 nslash = 0;
2029 nslash += 4;
2030 adrs += 1 << nslash;
2031 break;
2032 case '\\':
2033 if (nslash < 0)
2034 adrs += 1 << -nslash;
2035 else
2036 nslash = 0;
2037 nslash -= 4;
2038 adrs -= 1 << -nslash;
2039 break;
2040 case 'm':
2041 scanhex((void *)&adrs);
2042 break;
2043 case 'n':
2044 mnoread = 1;
2045 break;
2046 case 'r':
2047 brev = !brev;
2048 break;
2049 case '<':
2050 n = size;
2051 scanhex(&n);
2052 adrs -= n;
2053 break;
2054 case '>':
2055 n = size;
2056 scanhex(&n);
2057 adrs += n;
2058 break;
2059 case '?':
2060 printf(memex_subcmd_help_string);
2061 break;
2062 }
2063 }
2064 adrs += inc;
2065 }
2066}
2067
2068static int
2069bsesc(void)
2070{
2071 int c;
2072
2073 c = inchar();
2074 switch( c ){
2075 case 'n': c = '\n'; break;
2076 case 'r': c = '\r'; break;
2077 case 'b': c = '\b'; break;
2078 case 't': c = '\t'; break;
2079 }
2080 return c;
2081}
2082
2083static void xmon_rawdump (unsigned long adrs, long ndump)
2084{
2085 long n, m, r, nr;
2086 unsigned char temp[16];
2087
2088 for (n = ndump; n > 0;) {
2089 r = n < 16? n: 16;
2090 nr = mread(adrs, temp, r);
2091 adrs += nr;
2092 for (m = 0; m < r; ++m) {
2093 if (m < nr)
2094 printf("%.2x", temp[m]);
2095 else
2096 printf("%s", fault_chars[fault_type]);
2097 }
2098 n -= r;
2099 if (nr < r)
2100 break;
2101 }
2102 printf("\n");
2103}
2104
2105#ifdef CONFIG_PPC64
2106static void dump_one_paca(int cpu)
2107{
2108 struct paca_struct *p;
2109#ifdef CONFIG_PPC_STD_MMU_64
2110 int i = 0;
2111#endif
2112
2113 if (setjmp(bus_error_jmp) != 0) {
2114 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2115 return;
2116 }
2117
2118 catch_memory_errors = 1;
2119 sync();
2120
2121 p = &paca[cpu];
2122
2123 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2124
2125 printf(" %-*s = %s\n", 20, "possible", cpu_possible(cpu) ? "yes" : "no");
2126 printf(" %-*s = %s\n", 20, "present", cpu_present(cpu) ? "yes" : "no");
2127 printf(" %-*s = %s\n", 20, "online", cpu_online(cpu) ? "yes" : "no");
2128
2129#define DUMP(paca, name, format) \
2130 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 20, #name, 18, paca->name, \
2131 offsetof(struct paca_struct, name));
2132
2133 DUMP(p, lock_token, "x");
2134 DUMP(p, paca_index, "x");
2135 DUMP(p, kernel_toc, "lx");
2136 DUMP(p, kernelbase, "lx");
2137 DUMP(p, kernel_msr, "lx");
2138 DUMP(p, emergency_sp, "p");
2139#ifdef CONFIG_PPC_BOOK3S_64
2140 DUMP(p, mc_emergency_sp, "p");
2141 DUMP(p, in_mce, "x");
2142 DUMP(p, hmi_event_available, "x");
2143#endif
2144 DUMP(p, data_offset, "lx");
2145 DUMP(p, hw_cpu_id, "x");
2146 DUMP(p, cpu_start, "x");
2147 DUMP(p, kexec_state, "x");
2148#ifdef CONFIG_PPC_STD_MMU_64
2149 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2150 u64 esid, vsid;
2151
2152 if (!p->slb_shadow_ptr)
2153 continue;
2154
2155 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2156 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2157
2158 if (esid || vsid) {
2159 printf(" slb_shadow[%d]: = 0x%016lx 0x%016lx\n",
2160 i, esid, vsid);
2161 }
2162 }
2163 DUMP(p, vmalloc_sllp, "x");
2164 DUMP(p, slb_cache_ptr, "x");
2165 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2166 printf(" slb_cache[%d]: = 0x%016lx\n", i, p->slb_cache[i]);
2167#endif
2168 DUMP(p, dscr_default, "llx");
2169#ifdef CONFIG_PPC_BOOK3E
2170 DUMP(p, pgd, "p");
2171 DUMP(p, kernel_pgd, "p");
2172 DUMP(p, tcd_ptr, "p");
2173 DUMP(p, mc_kstack, "p");
2174 DUMP(p, crit_kstack, "p");
2175 DUMP(p, dbg_kstack, "p");
2176#endif
2177 DUMP(p, __current, "p");
2178 DUMP(p, kstack, "lx");
2179 DUMP(p, stab_rr, "lx");
2180 DUMP(p, saved_r1, "lx");
2181 DUMP(p, trap_save, "x");
2182 DUMP(p, soft_enabled, "x");
2183 DUMP(p, irq_happened, "x");
2184 DUMP(p, io_sync, "x");
2185 DUMP(p, irq_work_pending, "x");
2186 DUMP(p, nap_state_lost, "x");
2187 DUMP(p, sprg_vdso, "llx");
2188
2189#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2190 DUMP(p, tm_scratch, "llx");
2191#endif
2192
2193#ifdef CONFIG_PPC_POWERNV
2194 DUMP(p, core_idle_state_ptr, "p");
2195 DUMP(p, thread_idle_state, "x");
2196 DUMP(p, thread_mask, "x");
2197 DUMP(p, subcore_sibling_mask, "x");
2198#endif
2199
2200 DUMP(p, user_time, "llx");
2201 DUMP(p, system_time, "llx");
2202 DUMP(p, user_time_scaled, "llx");
2203 DUMP(p, starttime, "llx");
2204 DUMP(p, starttime_user, "llx");
2205 DUMP(p, startspurr, "llx");
2206 DUMP(p, utime_sspurr, "llx");
2207 DUMP(p, stolen_time, "llx");
2208#undef DUMP
2209
2210 catch_memory_errors = 0;
2211 sync();
2212}
2213
2214static void dump_all_pacas(void)
2215{
2216 int cpu;
2217
2218 if (num_possible_cpus() == 0) {
2219 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2220 return;
2221 }
2222
2223 for_each_possible_cpu(cpu)
2224 dump_one_paca(cpu);
2225}
2226
2227static void dump_pacas(void)
2228{
2229 unsigned long num;
2230 int c;
2231
2232 c = inchar();
2233 if (c == 'a') {
2234 dump_all_pacas();
2235 return;
2236 }
2237
2238 termch = c;
2239
2240 if (scanhex(&num))
2241 dump_one_paca(num);
2242 else
2243 dump_one_paca(xmon_owner);
2244}
2245#endif
2246
2247static void
2248dump(void)
2249{
2250 int c;
2251
2252 c = inchar();
2253
2254#ifdef CONFIG_PPC64
2255 if (c == 'p') {
2256 xmon_start_pagination();
2257 dump_pacas();
2258 xmon_end_pagination();
2259 return;
2260 }
2261#endif
2262
2263 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2264 termch = c;
2265 scanhex((void *)&adrs);
2266 if (termch != '\n')
2267 termch = 0;
2268 if (c == 'i') {
2269 scanhex(&nidump);
2270 if (nidump == 0)
2271 nidump = 16;
2272 else if (nidump > MAX_DUMP)
2273 nidump = MAX_DUMP;
2274 adrs += ppc_inst_dump(adrs, nidump, 1);
2275 last_cmd = "di\n";
2276 } else if (c == 'l') {
2277 dump_log_buf();
2278 } else if (c == 'o') {
2279 dump_opal_msglog();
2280 } else if (c == 'r') {
2281 scanhex(&ndump);
2282 if (ndump == 0)
2283 ndump = 64;
2284 xmon_rawdump(adrs, ndump);
2285 adrs += ndump;
2286 last_cmd = "dr\n";
2287 } else {
2288 scanhex(&ndump);
2289 if (ndump == 0)
2290 ndump = 64;
2291 else if (ndump > MAX_DUMP)
2292 ndump = MAX_DUMP;
2293 prdump(adrs, ndump);
2294 adrs += ndump;
2295 last_cmd = "d\n";
2296 }
2297}
2298
2299static void
2300prdump(unsigned long adrs, long ndump)
2301{
2302 long n, m, c, r, nr;
2303 unsigned char temp[16];
2304
2305 for (n = ndump; n > 0;) {
2306 printf(REG, adrs);
2307 putchar(' ');
2308 r = n < 16? n: 16;
2309 nr = mread(adrs, temp, r);
2310 adrs += nr;
2311 for (m = 0; m < r; ++m) {
2312 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2313 putchar(' ');
2314 if (m < nr)
2315 printf("%.2x", temp[m]);
2316 else
2317 printf("%s", fault_chars[fault_type]);
2318 }
2319 for (; m < 16; ++m) {
2320 if ((m & (sizeof(long) - 1)) == 0)
2321 putchar(' ');
2322 printf(" ");
2323 }
2324 printf(" |");
2325 for (m = 0; m < r; ++m) {
2326 if (m < nr) {
2327 c = temp[m];
2328 putchar(' ' <= c && c <= '~'? c: '.');
2329 } else
2330 putchar(' ');
2331 }
2332 n -= r;
2333 for (; m < 16; ++m)
2334 putchar(' ');
2335 printf("|\n");
2336 if (nr < r)
2337 break;
2338 }
2339}
2340
2341typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2342
2343static int
2344generic_inst_dump(unsigned long adr, long count, int praddr,
2345 instruction_dump_func dump_func)
2346{
2347 int nr, dotted;
2348 unsigned long first_adr;
2349 unsigned long inst, last_inst = 0;
2350 unsigned char val[4];
2351
2352 dotted = 0;
2353 for (first_adr = adr; count > 0; --count, adr += 4) {
2354 nr = mread(adr, val, 4);
2355 if (nr == 0) {
2356 if (praddr) {
2357 const char *x = fault_chars[fault_type];
2358 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2359 }
2360 break;
2361 }
2362 inst = GETWORD(val);
2363 if (adr > first_adr && inst == last_inst) {
2364 if (!dotted) {
2365 printf(" ...\n");
2366 dotted = 1;
2367 }
2368 continue;
2369 }
2370 dotted = 0;
2371 last_inst = inst;
2372 if (praddr)
2373 printf(REG" %.8x", adr, inst);
2374 printf("\t");
2375 dump_func(inst, adr);
2376 printf("\n");
2377 }
2378 return adr - first_adr;
2379}
2380
2381static int
2382ppc_inst_dump(unsigned long adr, long count, int praddr)
2383{
2384 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2385}
2386
2387void
2388print_address(unsigned long addr)
2389{
2390 xmon_print_symbol(addr, "\t# ", "");
2391}
2392
2393void
2394dump_log_buf(void)
2395{
2396 struct kmsg_dumper dumper = { .active = 1 };
2397 unsigned char buf[128];
2398 size_t len;
2399
2400 if (setjmp(bus_error_jmp) != 0) {
2401 printf("Error dumping printk buffer!\n");
2402 return;
2403 }
2404
2405 catch_memory_errors = 1;
2406 sync();
2407
2408 kmsg_dump_rewind_nolock(&dumper);
2409 xmon_start_pagination();
2410 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2411 buf[len] = '\0';
2412 printf("%s", buf);
2413 }
2414 xmon_end_pagination();
2415
2416 sync();
2417
2418 __delay(200);
2419 catch_memory_errors = 0;
2420}
2421
2422#ifdef CONFIG_PPC_POWERNV
2423static void dump_opal_msglog(void)
2424{
2425 unsigned char buf[128];
2426 ssize_t res;
2427 loff_t pos = 0;
2428
2429 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2430 printf("Machine is not running OPAL firmware.\n");
2431 return;
2432 }
2433
2434 if (setjmp(bus_error_jmp) != 0) {
2435 printf("Error dumping OPAL msglog!\n");
2436 return;
2437 }
2438
2439 catch_memory_errors = 1;
2440 sync();
2441
2442 xmon_start_pagination();
2443 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2444 if (res < 0) {
2445 printf("Error dumping OPAL msglog! Error: %zd\n", res);
2446 break;
2447 }
2448 buf[res] = '\0';
2449 printf("%s", buf);
2450 pos += res;
2451 }
2452 xmon_end_pagination();
2453
2454 sync();
2455
2456 __delay(200);
2457 catch_memory_errors = 0;
2458}
2459#endif
2460
2461
2462
2463
2464static unsigned long mdest;
2465static unsigned long msrc;
2466static unsigned long mval;
2467static unsigned long mcount;
2468static unsigned long mdiffs;
2469
2470static void
2471memops(int cmd)
2472{
2473 scanhex((void *)&mdest);
2474 if( termch != '\n' )
2475 termch = 0;
2476 scanhex((void *)(cmd == 's'? &mval: &msrc));
2477 if( termch != '\n' )
2478 termch = 0;
2479 scanhex((void *)&mcount);
2480 switch( cmd ){
2481 case 'm':
2482 memmove((void *)mdest, (void *)msrc, mcount);
2483 break;
2484 case 's':
2485 memset((void *)mdest, mval, mcount);
2486 break;
2487 case 'd':
2488 if( termch != '\n' )
2489 termch = 0;
2490 scanhex((void *)&mdiffs);
2491 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2492 break;
2493 }
2494}
2495
2496static void
2497memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2498{
2499 unsigned n, prt;
2500
2501 prt = 0;
2502 for( n = nb; n > 0; --n )
2503 if( *p1++ != *p2++ )
2504 if( ++prt <= maxpr )
2505 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2506 p1[-1], p2 - 1, p2[-1]);
2507 if( prt > maxpr )
2508 printf("Total of %d differences\n", prt);
2509}
2510
2511static unsigned mend;
2512static unsigned mask;
2513
2514static void
2515memlocate(void)
2516{
2517 unsigned a, n;
2518 unsigned char val[4];
2519
2520 last_cmd = "ml";
2521 scanhex((void *)&mdest);
2522 if (termch != '\n') {
2523 termch = 0;
2524 scanhex((void *)&mend);
2525 if (termch != '\n') {
2526 termch = 0;
2527 scanhex((void *)&mval);
2528 mask = ~0;
2529 if (termch != '\n') termch = 0;
2530 scanhex((void *)&mask);
2531 }
2532 }
2533 n = 0;
2534 for (a = mdest; a < mend; a += 4) {
2535 if (mread(a, val, 4) == 4
2536 && ((GETWORD(val) ^ mval) & mask) == 0) {
2537 printf("%.16x: %.16x\n", a, GETWORD(val));
2538 if (++n >= 10)
2539 break;
2540 }
2541 }
2542}
2543
2544static unsigned long mskip = 0x1000;
2545static unsigned long mlim = 0xffffffff;
2546
2547static void
2548memzcan(void)
2549{
2550 unsigned char v;
2551 unsigned a;
2552 int ok, ook;
2553
2554 scanhex(&mdest);
2555 if (termch != '\n') termch = 0;
2556 scanhex(&mskip);
2557 if (termch != '\n') termch = 0;
2558 scanhex(&mlim);
2559 ook = 0;
2560 for (a = mdest; a < mlim; a += mskip) {
2561 ok = mread(a, &v, 1);
2562 if (ok && !ook) {
2563 printf("%.8x .. ", a);
2564 } else if (!ok && ook)
2565 printf("%.8x\n", a - mskip);
2566 ook = ok;
2567 if (a + mskip < a)
2568 break;
2569 }
2570 if (ook)
2571 printf("%.8x\n", a - mskip);
2572}
2573
2574static void show_task(struct task_struct *tsk)
2575{
2576 char state;
2577
2578
2579
2580
2581
2582
2583 state = (tsk->state == 0) ? 'R' :
2584 (tsk->state < 0) ? 'U' :
2585 (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
2586 (tsk->state & TASK_STOPPED) ? 'T' :
2587 (tsk->state & TASK_TRACED) ? 'C' :
2588 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
2589 (tsk->exit_state & EXIT_DEAD) ? 'E' :
2590 (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
2591
2592 printf("%p %016lx %6d %6d %c %2d %s\n", tsk,
2593 tsk->thread.ksp,
2594 tsk->pid, tsk->parent->pid,
2595 state, task_thread_info(tsk)->cpu,
2596 tsk->comm);
2597}
2598
2599static void show_tasks(void)
2600{
2601 unsigned long tskv;
2602 struct task_struct *tsk = NULL;
2603
2604 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
2605
2606 if (scanhex(&tskv))
2607 tsk = (struct task_struct *)tskv;
2608
2609 if (setjmp(bus_error_jmp) != 0) {
2610 catch_memory_errors = 0;
2611 printf("*** Error dumping task %p\n", tsk);
2612 return;
2613 }
2614
2615 catch_memory_errors = 1;
2616 sync();
2617
2618 if (tsk)
2619 show_task(tsk);
2620 else
2621 for_each_process(tsk)
2622 show_task(tsk);
2623
2624 sync();
2625 __delay(200);
2626 catch_memory_errors = 0;
2627}
2628
2629static void proccall(void)
2630{
2631 unsigned long args[8];
2632 unsigned long ret;
2633 int i;
2634 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2635 unsigned long, unsigned long, unsigned long,
2636 unsigned long, unsigned long, unsigned long);
2637 callfunc_t func;
2638
2639 if (!scanhex(&adrs))
2640 return;
2641 if (termch != '\n')
2642 termch = 0;
2643 for (i = 0; i < 8; ++i)
2644 args[i] = 0;
2645 for (i = 0; i < 8; ++i) {
2646 if (!scanhex(&args[i]) || termch == '\n')
2647 break;
2648 termch = 0;
2649 }
2650 func = (callfunc_t) adrs;
2651 ret = 0;
2652 if (setjmp(bus_error_jmp) == 0) {
2653 catch_memory_errors = 1;
2654 sync();
2655 ret = func(args[0], args[1], args[2], args[3],
2656 args[4], args[5], args[6], args[7]);
2657 sync();
2658 printf("return value is 0x%lx\n", ret);
2659 } else {
2660 printf("*** %x exception occurred\n", fault_except);
2661 }
2662 catch_memory_errors = 0;
2663}
2664
2665
2666int
2667skipbl(void)
2668{
2669 int c;
2670
2671 if( termch != 0 ){
2672 c = termch;
2673 termch = 0;
2674 } else
2675 c = inchar();
2676 while( c == ' ' || c == '\t' )
2677 c = inchar();
2678 return c;
2679}
2680
2681#define N_PTREGS 44
2682static char *regnames[N_PTREGS] = {
2683 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2684 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2685 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2686 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2687 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2688#ifdef CONFIG_PPC64
2689 "softe",
2690#else
2691 "mq",
2692#endif
2693 "trap", "dar", "dsisr", "res"
2694};
2695
2696int
2697scanhex(unsigned long *vp)
2698{
2699 int c, d;
2700 unsigned long v;
2701
2702 c = skipbl();
2703 if (c == '%') {
2704
2705 char regname[8];
2706 int i;
2707
2708 for (i = 0; i < sizeof(regname) - 1; ++i) {
2709 c = inchar();
2710 if (!isalnum(c)) {
2711 termch = c;
2712 break;
2713 }
2714 regname[i] = c;
2715 }
2716 regname[i] = 0;
2717 for (i = 0; i < N_PTREGS; ++i) {
2718 if (strcmp(regnames[i], regname) == 0) {
2719 if (xmon_regs == NULL) {
2720 printf("regs not available\n");
2721 return 0;
2722 }
2723 *vp = ((unsigned long *)xmon_regs)[i];
2724 return 1;
2725 }
2726 }
2727 printf("invalid register name '%%%s'\n", regname);
2728 return 0;
2729 }
2730
2731
2732
2733 if (c == '0') {
2734 c = inchar();
2735 if (c == 'x') {
2736 c = inchar();
2737 } else {
2738 d = hexdigit(c);
2739 if (d == EOF) {
2740 termch = c;
2741 *vp = 0;
2742 return 1;
2743 }
2744 }
2745 } else if (c == '$') {
2746 int i;
2747 for (i=0; i<63; i++) {
2748 c = inchar();
2749 if (isspace(c) || c == '\0') {
2750 termch = c;
2751 break;
2752 }
2753 tmpstr[i] = c;
2754 }
2755 tmpstr[i++] = 0;
2756 *vp = 0;
2757 if (setjmp(bus_error_jmp) == 0) {
2758 catch_memory_errors = 1;
2759 sync();
2760 *vp = kallsyms_lookup_name(tmpstr);
2761 sync();
2762 }
2763 catch_memory_errors = 0;
2764 if (!(*vp)) {
2765 printf("unknown symbol '%s'\n", tmpstr);
2766 return 0;
2767 }
2768 return 1;
2769 }
2770
2771 d = hexdigit(c);
2772 if (d == EOF) {
2773 termch = c;
2774 return 0;
2775 }
2776 v = 0;
2777 do {
2778 v = (v << 4) + d;
2779 c = inchar();
2780 d = hexdigit(c);
2781 } while (d != EOF);
2782 termch = c;
2783 *vp = v;
2784 return 1;
2785}
2786
2787static void
2788scannl(void)
2789{
2790 int c;
2791
2792 c = termch;
2793 termch = 0;
2794 while( c != '\n' )
2795 c = inchar();
2796}
2797
2798static int hexdigit(int c)
2799{
2800 if( '0' <= c && c <= '9' )
2801 return c - '0';
2802 if( 'A' <= c && c <= 'F' )
2803 return c - ('A' - 10);
2804 if( 'a' <= c && c <= 'f' )
2805 return c - ('a' - 10);
2806 return EOF;
2807}
2808
2809void
2810getstring(char *s, int size)
2811{
2812 int c;
2813
2814 c = skipbl();
2815 do {
2816 if( size > 1 ){
2817 *s++ = c;
2818 --size;
2819 }
2820 c = inchar();
2821 } while( c != ' ' && c != '\t' && c != '\n' );
2822 termch = c;
2823 *s = 0;
2824}
2825
2826static char line[256];
2827static char *lineptr;
2828
2829static void
2830flush_input(void)
2831{
2832 lineptr = NULL;
2833}
2834
2835static int
2836inchar(void)
2837{
2838 if (lineptr == NULL || *lineptr == 0) {
2839 if (xmon_gets(line, sizeof(line)) == NULL) {
2840 lineptr = NULL;
2841 return EOF;
2842 }
2843 lineptr = line;
2844 }
2845 return *lineptr++;
2846}
2847
2848static void
2849take_input(char *str)
2850{
2851 lineptr = str;
2852}
2853
2854
2855static void
2856symbol_lookup(void)
2857{
2858 int type = inchar();
2859 unsigned long addr;
2860 static char tmp[64];
2861
2862 switch (type) {
2863 case 'a':
2864 if (scanhex(&addr))
2865 xmon_print_symbol(addr, ": ", "\n");
2866 termch = 0;
2867 break;
2868 case 's':
2869 getstring(tmp, 64);
2870 if (setjmp(bus_error_jmp) == 0) {
2871 catch_memory_errors = 1;
2872 sync();
2873 addr = kallsyms_lookup_name(tmp);
2874 if (addr)
2875 printf("%s: %lx\n", tmp, addr);
2876 else
2877 printf("Symbol '%s' not found.\n", tmp);
2878 sync();
2879 }
2880 catch_memory_errors = 0;
2881 termch = 0;
2882 break;
2883 }
2884}
2885
2886
2887
2888static void xmon_print_symbol(unsigned long address, const char *mid,
2889 const char *after)
2890{
2891 char *modname;
2892 const char *name = NULL;
2893 unsigned long offset, size;
2894
2895 printf(REG, address);
2896 if (setjmp(bus_error_jmp) == 0) {
2897 catch_memory_errors = 1;
2898 sync();
2899 name = kallsyms_lookup(address, &size, &offset, &modname,
2900 tmpstr);
2901 sync();
2902
2903 __delay(200);
2904 }
2905
2906 catch_memory_errors = 0;
2907
2908 if (name) {
2909 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2910 if (modname)
2911 printf(" [%s]", modname);
2912 }
2913 printf("%s", after);
2914}
2915
2916#ifdef CONFIG_PPC_BOOK3S_64
2917void dump_segments(void)
2918{
2919 int i;
2920 unsigned long esid,vsid;
2921 unsigned long llp;
2922
2923 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
2924
2925 for (i = 0; i < mmu_slb_size; i++) {
2926 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2927 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2928 if (esid || vsid) {
2929 printf("%02d %016lx %016lx", i, esid, vsid);
2930 if (esid & SLB_ESID_V) {
2931 llp = vsid & SLB_VSID_LLP;
2932 if (vsid & SLB_VSID_B_1T) {
2933 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2934 GET_ESID_1T(esid),
2935 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2936 llp);
2937 } else {
2938 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2939 GET_ESID(esid),
2940 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2941 llp);
2942 }
2943 } else
2944 printf("\n");
2945 }
2946 }
2947}
2948#endif
2949
2950#ifdef CONFIG_PPC_STD_MMU_32
2951void dump_segments(void)
2952{
2953 int i;
2954
2955 printf("sr0-15 =");
2956 for (i = 0; i < 16; ++i)
2957 printf(" %x", mfsrin(i));
2958 printf("\n");
2959}
2960#endif
2961
2962#ifdef CONFIG_44x
2963static void dump_tlb_44x(void)
2964{
2965 int i;
2966
2967 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2968 unsigned long w0,w1,w2;
2969 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2970 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2971 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2972 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2973 if (w0 & PPC44x_TLB_VALID) {
2974 printf("V %08x -> %01x%08x %c%c%c%c%c",
2975 w0 & PPC44x_TLB_EPN_MASK,
2976 w1 & PPC44x_TLB_ERPN_MASK,
2977 w1 & PPC44x_TLB_RPN_MASK,
2978 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2979 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2980 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2981 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2982 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2983 }
2984 printf("\n");
2985 }
2986}
2987#endif
2988
2989#ifdef CONFIG_PPC_BOOK3E
2990static void dump_tlb_book3e(void)
2991{
2992 u32 mmucfg, pidmask, lpidmask;
2993 u64 ramask;
2994 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2995 int mmu_version;
2996 static const char *pgsz_names[] = {
2997 " 1K",
2998 " 2K",
2999 " 4K",
3000 " 8K",
3001 " 16K",
3002 " 32K",
3003 " 64K",
3004 "128K",
3005 "256K",
3006 "512K",
3007 " 1M",
3008 " 2M",
3009 " 4M",
3010 " 8M",
3011 " 16M",
3012 " 32M",
3013 " 64M",
3014 "128M",
3015 "256M",
3016 "512M",
3017 " 1G",
3018 " 2G",
3019 " 4G",
3020 " 8G",
3021 " 16G",
3022 " 32G",
3023 " 64G",
3024 "128G",
3025 "256G",
3026 "512G",
3027 " 1T",
3028 " 2T",
3029 };
3030
3031
3032 mmucfg = mfspr(SPRN_MMUCFG);
3033 mmu_version = (mmucfg & 3) + 1;
3034 ntlbs = ((mmucfg >> 2) & 3) + 1;
3035 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3036 lpidsz = (mmucfg >> 24) & 0xf;
3037 rasz = (mmucfg >> 16) & 0x7f;
3038 if ((mmu_version > 1) && (mmucfg & 0x10000))
3039 lrat = 1;
3040 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3041 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3042 pidmask = (1ul << pidsz) - 1;
3043 lpidmask = (1ul << lpidsz) - 1;
3044 ramask = (1ull << rasz) - 1;
3045
3046 for (tlb = 0; tlb < ntlbs; tlb++) {
3047 u32 tlbcfg;
3048 int nent, assoc, new_cc = 1;
3049 printf("TLB %d:\n------\n", tlb);
3050 switch(tlb) {
3051 case 0:
3052 tlbcfg = mfspr(SPRN_TLB0CFG);
3053 break;
3054 case 1:
3055 tlbcfg = mfspr(SPRN_TLB1CFG);
3056 break;
3057 case 2:
3058 tlbcfg = mfspr(SPRN_TLB2CFG);
3059 break;
3060 case 3:
3061 tlbcfg = mfspr(SPRN_TLB3CFG);
3062 break;
3063 default:
3064 printf("Unsupported TLB number !\n");
3065 continue;
3066 }
3067 nent = tlbcfg & 0xfff;
3068 assoc = (tlbcfg >> 24) & 0xff;
3069 for (i = 0; i < nent; i++) {
3070 u32 mas0 = MAS0_TLBSEL(tlb);
3071 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3072 u64 mas2 = 0;
3073 u64 mas7_mas3;
3074 int esel = i, cc = i;
3075
3076 if (assoc != 0) {
3077 cc = i / assoc;
3078 esel = i % assoc;
3079 mas2 = cc * 0x1000;
3080 }
3081
3082 mas0 |= MAS0_ESEL(esel);
3083 mtspr(SPRN_MAS0, mas0);
3084 mtspr(SPRN_MAS1, mas1);
3085 mtspr(SPRN_MAS2, mas2);
3086 asm volatile("tlbre 0,0,0" : : : "memory");
3087 mas1 = mfspr(SPRN_MAS1);
3088 mas2 = mfspr(SPRN_MAS2);
3089 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3090 if (assoc && (i % assoc) == 0)
3091 new_cc = 1;
3092 if (!(mas1 & MAS1_VALID))
3093 continue;
3094 if (assoc == 0)
3095 printf("%04x- ", i);
3096 else if (new_cc)
3097 printf("%04x-%c", cc, 'A' + esel);
3098 else
3099 printf(" |%c", 'A' + esel);
3100 new_cc = 0;
3101 printf(" %016llx %04x %s %c%c AS%c",
3102 mas2 & ~0x3ffull,
3103 (mas1 >> 16) & 0x3fff,
3104 pgsz_names[(mas1 >> 7) & 0x1f],
3105 mas1 & MAS1_IND ? 'I' : ' ',
3106 mas1 & MAS1_IPROT ? 'P' : ' ',
3107 mas1 & MAS1_TS ? '1' : '0');
3108 printf(" %c%c%c%c%c%c%c",
3109 mas2 & MAS2_X0 ? 'a' : ' ',
3110 mas2 & MAS2_X1 ? 'v' : ' ',
3111 mas2 & MAS2_W ? 'w' : ' ',
3112 mas2 & MAS2_I ? 'i' : ' ',
3113 mas2 & MAS2_M ? 'm' : ' ',
3114 mas2 & MAS2_G ? 'g' : ' ',
3115 mas2 & MAS2_E ? 'e' : ' ');
3116 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3117 if (mas1 & MAS1_IND)
3118 printf(" %s\n",
3119 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3120 else
3121 printf(" U%c%c%c S%c%c%c\n",
3122 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3123 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3124 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3125 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3126 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3127 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3128 }
3129 }
3130}
3131#endif
3132
3133static void xmon_init(int enable)
3134{
3135 if (enable) {
3136 __debugger = xmon;
3137 __debugger_ipi = xmon_ipi;
3138 __debugger_bpt = xmon_bpt;
3139 __debugger_sstep = xmon_sstep;
3140 __debugger_iabr_match = xmon_iabr_match;
3141 __debugger_break_match = xmon_break_match;
3142 __debugger_fault_handler = xmon_fault_handler;
3143 } else {
3144 __debugger = NULL;
3145 __debugger_ipi = NULL;
3146 __debugger_bpt = NULL;
3147 __debugger_sstep = NULL;
3148 __debugger_iabr_match = NULL;
3149 __debugger_break_match = NULL;
3150 __debugger_fault_handler = NULL;
3151 }
3152}
3153
3154#ifdef CONFIG_MAGIC_SYSRQ
3155static void sysrq_handle_xmon(int key)
3156{
3157
3158 xmon_init(1);
3159 debugger(get_irq_regs());
3160}
3161
3162static struct sysrq_key_op sysrq_xmon_op = {
3163 .handler = sysrq_handle_xmon,
3164 .help_msg = "xmon(x)",
3165 .action_msg = "Entering xmon",
3166};
3167
3168static int __init setup_xmon_sysrq(void)
3169{
3170 register_sysrq_key('x', &sysrq_xmon_op);
3171 return 0;
3172}
3173__initcall(setup_xmon_sysrq);
3174#endif
3175
3176static int __initdata xmon_early, xmon_off;
3177
3178static int __init early_parse_xmon(char *p)
3179{
3180 if (!p || strncmp(p, "early", 5) == 0) {
3181
3182 xmon_init(1);
3183 xmon_early = 1;
3184 } else if (strncmp(p, "on", 2) == 0)
3185 xmon_init(1);
3186 else if (strncmp(p, "off", 3) == 0)
3187 xmon_off = 1;
3188 else if (strncmp(p, "nobt", 4) == 0)
3189 xmon_no_auto_backtrace = 1;
3190 else
3191 return 1;
3192
3193 return 0;
3194}
3195early_param("xmon", early_parse_xmon);
3196
3197void __init xmon_setup(void)
3198{
3199#ifdef CONFIG_XMON_DEFAULT
3200 if (!xmon_off)
3201 xmon_init(1);
3202#endif
3203 if (xmon_early)
3204 debugger(NULL);
3205}
3206
3207#ifdef CONFIG_SPU_BASE
3208
3209struct spu_info {
3210 struct spu *spu;
3211 u64 saved_mfc_sr1_RW;
3212 u32 saved_spu_runcntl_RW;
3213 unsigned long dump_addr;
3214 u8 stopped_ok;
3215};
3216
3217#define XMON_NUM_SPUS 16
3218
3219static struct spu_info spu_info[XMON_NUM_SPUS];
3220
3221void xmon_register_spus(struct list_head *list)
3222{
3223 struct spu *spu;
3224
3225 list_for_each_entry(spu, list, full_list) {
3226 if (spu->number >= XMON_NUM_SPUS) {
3227 WARN_ON(1);
3228 continue;
3229 }
3230
3231 spu_info[spu->number].spu = spu;
3232 spu_info[spu->number].stopped_ok = 0;
3233 spu_info[spu->number].dump_addr = (unsigned long)
3234 spu_info[spu->number].spu->local_store;
3235 }
3236}
3237
3238static void stop_spus(void)
3239{
3240 struct spu *spu;
3241 int i;
3242 u64 tmp;
3243
3244 for (i = 0; i < XMON_NUM_SPUS; i++) {
3245 if (!spu_info[i].spu)
3246 continue;
3247
3248 if (setjmp(bus_error_jmp) == 0) {
3249 catch_memory_errors = 1;
3250 sync();
3251
3252 spu = spu_info[i].spu;
3253
3254 spu_info[i].saved_spu_runcntl_RW =
3255 in_be32(&spu->problem->spu_runcntl_RW);
3256
3257 tmp = spu_mfc_sr1_get(spu);
3258 spu_info[i].saved_mfc_sr1_RW = tmp;
3259
3260 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3261 spu_mfc_sr1_set(spu, tmp);
3262
3263 sync();
3264 __delay(200);
3265
3266 spu_info[i].stopped_ok = 1;
3267
3268 printf("Stopped spu %.2d (was %s)\n", i,
3269 spu_info[i].saved_spu_runcntl_RW ?
3270 "running" : "stopped");
3271 } else {
3272 catch_memory_errors = 0;
3273 printf("*** Error stopping spu %.2d\n", i);
3274 }
3275 catch_memory_errors = 0;
3276 }
3277}
3278
3279static void restart_spus(void)
3280{
3281 struct spu *spu;
3282 int i;
3283
3284 for (i = 0; i < XMON_NUM_SPUS; i++) {
3285 if (!spu_info[i].spu)
3286 continue;
3287
3288 if (!spu_info[i].stopped_ok) {
3289 printf("*** Error, spu %d was not successfully stopped"
3290 ", not restarting\n", i);
3291 continue;
3292 }
3293
3294 if (setjmp(bus_error_jmp) == 0) {
3295 catch_memory_errors = 1;
3296 sync();
3297
3298 spu = spu_info[i].spu;
3299 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3300 out_be32(&spu->problem->spu_runcntl_RW,
3301 spu_info[i].saved_spu_runcntl_RW);
3302
3303 sync();
3304 __delay(200);
3305
3306 printf("Restarted spu %.2d\n", i);
3307 } else {
3308 catch_memory_errors = 0;
3309 printf("*** Error restarting spu %.2d\n", i);
3310 }
3311 catch_memory_errors = 0;
3312 }
3313}
3314
3315#define DUMP_WIDTH 23
3316#define DUMP_VALUE(format, field, value) \
3317do { \
3318 if (setjmp(bus_error_jmp) == 0) { \
3319 catch_memory_errors = 1; \
3320 sync(); \
3321 printf(" %-*s = "format"\n", DUMP_WIDTH, \
3322 #field, value); \
3323 sync(); \
3324 __delay(200); \
3325 } else { \
3326 catch_memory_errors = 0; \
3327 printf(" %-*s = *** Error reading field.\n", \
3328 DUMP_WIDTH, #field); \
3329 } \
3330 catch_memory_errors = 0; \
3331} while (0)
3332
3333#define DUMP_FIELD(obj, format, field) \
3334 DUMP_VALUE(format, field, obj->field)
3335
3336static void dump_spu_fields(struct spu *spu)
3337{
3338 printf("Dumping spu fields at address %p:\n", spu);
3339
3340 DUMP_FIELD(spu, "0x%x", number);
3341 DUMP_FIELD(spu, "%s", name);
3342 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3343 DUMP_FIELD(spu, "0x%p", local_store);
3344 DUMP_FIELD(spu, "0x%lx", ls_size);
3345 DUMP_FIELD(spu, "0x%x", node);
3346 DUMP_FIELD(spu, "0x%lx", flags);
3347 DUMP_FIELD(spu, "%d", class_0_pending);
3348 DUMP_FIELD(spu, "0x%lx", class_0_dar);
3349 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3350 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3351 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3352 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3353 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3354 DUMP_FIELD(spu, "0x%x", slb_replace);
3355 DUMP_FIELD(spu, "%d", pid);
3356 DUMP_FIELD(spu, "0x%p", mm);
3357 DUMP_FIELD(spu, "0x%p", ctx);
3358 DUMP_FIELD(spu, "0x%p", rq);
3359 DUMP_FIELD(spu, "0x%p", timestamp);
3360 DUMP_FIELD(spu, "0x%lx", problem_phys);
3361 DUMP_FIELD(spu, "0x%p", problem);
3362 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3363 in_be32(&spu->problem->spu_runcntl_RW));
3364 DUMP_VALUE("0x%x", problem->spu_status_R,
3365 in_be32(&spu->problem->spu_status_R));
3366 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3367 in_be32(&spu->problem->spu_npc_RW));
3368 DUMP_FIELD(spu, "0x%p", priv2);
3369 DUMP_FIELD(spu, "0x%p", pdata);
3370}
3371
3372int
3373spu_inst_dump(unsigned long adr, long count, int praddr)
3374{
3375 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3376}
3377
3378static void dump_spu_ls(unsigned long num, int subcmd)
3379{
3380 unsigned long offset, addr, ls_addr;
3381
3382 if (setjmp(bus_error_jmp) == 0) {
3383 catch_memory_errors = 1;
3384 sync();
3385 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3386 sync();
3387 __delay(200);
3388 } else {
3389 catch_memory_errors = 0;
3390 printf("*** Error: accessing spu info for spu %d\n", num);
3391 return;
3392 }
3393 catch_memory_errors = 0;
3394
3395 if (scanhex(&offset))
3396 addr = ls_addr + offset;
3397 else
3398 addr = spu_info[num].dump_addr;
3399
3400 if (addr >= ls_addr + LS_SIZE) {
3401 printf("*** Error: address outside of local store\n");
3402 return;
3403 }
3404
3405 switch (subcmd) {
3406 case 'i':
3407 addr += spu_inst_dump(addr, 16, 1);
3408 last_cmd = "sdi\n";
3409 break;
3410 default:
3411 prdump(addr, 64);
3412 addr += 64;
3413 last_cmd = "sd\n";
3414 break;
3415 }
3416
3417 spu_info[num].dump_addr = addr;
3418}
3419
3420static int do_spu_cmd(void)
3421{
3422 static unsigned long num = 0;
3423 int cmd, subcmd = 0;
3424
3425 cmd = inchar();
3426 switch (cmd) {
3427 case 's':
3428 stop_spus();
3429 break;
3430 case 'r':
3431 restart_spus();
3432 break;
3433 case 'd':
3434 subcmd = inchar();
3435 if (isxdigit(subcmd) || subcmd == '\n')
3436 termch = subcmd;
3437 case 'f':
3438 scanhex(&num);
3439 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3440 printf("*** Error: invalid spu number\n");
3441 return 0;
3442 }
3443
3444 switch (cmd) {
3445 case 'f':
3446 dump_spu_fields(spu_info[num].spu);
3447 break;
3448 default:
3449 dump_spu_ls(num, subcmd);
3450 break;
3451 }
3452
3453 break;
3454 default:
3455 return -1;
3456 }
3457
3458 return 0;
3459}
3460#else
3461static int do_spu_cmd(void)
3462{
3463 return -1;
3464}
3465#endif
3466