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