1
2
3
4
5
6
7
8
9
10#include <linux/kernel.h>
11#include <linux/errno.h>
12#include <linux/sched/signal.h>
13#include <linux/smp.h>
14#include <linux/mm.h>
15#include <linux/reboot.h>
16#include <linux/delay.h>
17#include <linux/kallsyms.h>
18#include <linux/kmsg_dump.h>
19#include <linux/cpumask.h>
20#include <linux/export.h>
21#include <linux/sysrq.h>
22#include <linux/interrupt.h>
23#include <linux/irq.h>
24#include <linux/bug.h>
25#include <linux/nmi.h>
26#include <linux/ctype.h>
27#include <linux/highmem.h>
28#include <linux/security.h>
29
30#include <asm/debugfs.h>
31#include <asm/ptrace.h>
32#include <asm/smp.h>
33#include <asm/string.h>
34#include <asm/prom.h>
35#include <asm/machdep.h>
36#include <asm/xmon.h>
37#include <asm/processor.h>
38#include <asm/mmu.h>
39#include <asm/mmu_context.h>
40#include <asm/plpar_wrappers.h>
41#include <asm/cputable.h>
42#include <asm/rtas.h>
43#include <asm/sstep.h>
44#include <asm/irq_regs.h>
45#include <asm/spu.h>
46#include <asm/spu_priv1.h>
47#include <asm/setjmp.h>
48#include <asm/reg.h>
49#include <asm/debug.h>
50#include <asm/hw_breakpoint.h>
51#include <asm/xive.h>
52#include <asm/opal.h>
53#include <asm/firmware.h>
54#include <asm/code-patching.h>
55#include <asm/sections.h>
56#include <asm/inst.h>
57#include <asm/interrupt.h>
58
59#ifdef CONFIG_PPC64
60#include <asm/hvcall.h>
61#include <asm/paca.h>
62#endif
63
64#include "nonstdio.h"
65#include "dis-asm.h"
66#include "xmon_bpts.h"
67
68#ifdef CONFIG_SMP
69static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
70static unsigned long xmon_taken = 1;
71static int xmon_owner;
72static int xmon_gate;
73static int xmon_batch;
74static unsigned long xmon_batch_start_cpu;
75static cpumask_t xmon_batch_cpus = CPU_MASK_NONE;
76#else
77#define xmon_owner 0
78#endif
79
80#ifdef CONFIG_PPC_PSERIES
81static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
82#endif
83static unsigned long in_xmon __read_mostly = 0;
84static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
85static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
86
87static unsigned long adrs;
88static int size = 1;
89#define MAX_DUMP (64 * 1024)
90static unsigned long ndump = 64;
91#define MAX_IDUMP (MAX_DUMP >> 2)
92static unsigned long nidump = 16;
93static unsigned long ncsum = 4096;
94static int termch;
95static char tmpstr[128];
96static int tracing_enabled;
97
98static long bus_error_jmp[JMP_BUF_LEN];
99static int catch_memory_errors;
100static int catch_spr_faults;
101static long *xmon_fault_jmp[NR_CPUS];
102
103
104struct bpt {
105 unsigned long address;
106 u32 *instr;
107 atomic_t ref_count;
108 int enabled;
109 unsigned long pad;
110};
111
112
113#define BP_CIABR 1
114#define BP_TRAP 2
115#define BP_DABR 4
116
117static struct bpt bpts[NBPTS];
118static struct bpt dabr[HBP_NUM_MAX];
119static struct bpt *iabr;
120static unsigned bpinstr = 0x7fe00008;
121
122#define BP_NUM(bp) ((bp) - bpts + 1)
123
124
125static int cmds(struct pt_regs *);
126static int mread(unsigned long, void *, int);
127static int mwrite(unsigned long, void *, int);
128static int mread_instr(unsigned long, struct ppc_inst *);
129static int handle_fault(struct pt_regs *);
130static void byterev(unsigned char *, int);
131static void memex(void);
132static int bsesc(void);
133static void dump(void);
134static void show_pte(unsigned long);
135static void prdump(unsigned long, long);
136static int ppc_inst_dump(unsigned long, long, int);
137static void dump_log_buf(void);
138
139#ifdef CONFIG_SMP
140static int xmon_switch_cpu(unsigned long);
141static int xmon_batch_next_cpu(void);
142static int batch_cmds(struct pt_regs *);
143#endif
144
145#ifdef CONFIG_PPC_POWERNV
146static void dump_opal_msglog(void);
147#else
148static inline void dump_opal_msglog(void)
149{
150 printf("Machine is not running OPAL firmware.\n");
151}
152#endif
153
154static void backtrace(struct pt_regs *);
155static void excprint(struct pt_regs *);
156static void prregs(struct pt_regs *);
157static void memops(int);
158static void memlocate(void);
159static void memzcan(void);
160static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
161int skipbl(void);
162int scanhex(unsigned long *valp);
163static void scannl(void);
164static int hexdigit(int);
165void getstring(char *, int);
166static void flush_input(void);
167static int inchar(void);
168static void take_input(char *);
169static int read_spr(int, unsigned long *);
170static void write_spr(int, unsigned long);
171static void super_regs(void);
172static void remove_bpts(void);
173static void insert_bpts(void);
174static void remove_cpu_bpts(void);
175static void insert_cpu_bpts(void);
176static struct bpt *at_breakpoint(unsigned long pc);
177static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
178static int do_step(struct pt_regs *);
179static void bpt_cmds(void);
180static void cacheflush(void);
181static int cpu_cmd(void);
182static void csum(void);
183static void bootcmds(void);
184static void proccall(void);
185static void show_tasks(void);
186void dump_segments(void);
187static void symbol_lookup(void);
188static void xmon_show_stack(unsigned long sp, unsigned long lr,
189 unsigned long pc);
190static void xmon_print_symbol(unsigned long address, const char *mid,
191 const char *after);
192static const char *getvecname(unsigned long vec);
193
194static int do_spu_cmd(void);
195
196#ifdef CONFIG_44x
197static void dump_tlb_44x(void);
198#endif
199#ifdef CONFIG_PPC_BOOK3E
200static void dump_tlb_book3e(void);
201#endif
202
203static void clear_all_bpt(void);
204
205#ifdef CONFIG_PPC64
206#define REG "%.16lx"
207#else
208#define REG "%.8lx"
209#endif
210
211#ifdef __LITTLE_ENDIAN__
212#define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
213#else
214#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
215#endif
216
217static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
218
219static char *help_string = "\
220Commands:\n\
221 b show breakpoints\n\
222 bd set data breakpoint\n\
223 bi set instruction breakpoint\n\
224 bc clear breakpoint\n"
225#ifdef CONFIG_SMP
226 "\
227 c print cpus stopped in xmon\n\
228 c# try to switch to cpu number h (in hex)\n\
229 c# $ run command '$' (one of 'r','S' or 't') on all cpus in xmon\n"
230#endif
231 "\
232 C checksum\n\
233 d dump bytes\n\
234 d1 dump 1 byte values\n\
235 d2 dump 2 byte values\n\
236 d4 dump 4 byte values\n\
237 d8 dump 8 byte values\n\
238 di dump instructions\n\
239 df dump float values\n\
240 dd dump double values\n\
241 dl dump the kernel log buffer\n"
242#ifdef CONFIG_PPC_POWERNV
243 "\
244 do dump the OPAL message log\n"
245#endif
246#ifdef CONFIG_PPC64
247 "\
248 dp[#] dump paca for current cpu, or cpu #\n\
249 dpa dump paca for all possible cpus\n"
250#endif
251 "\
252 dr dump stream of raw bytes\n\
253 dv dump virtual address translation \n\
254 dt dump the tracing buffers (uses printk)\n\
255 dtc dump the tracing buffers for current CPU (uses printk)\n\
256"
257#ifdef CONFIG_PPC_POWERNV
258" dx# dump xive on CPU #\n\
259 dxi# dump xive irq state #\n\
260 dxa dump xive on all CPUs\n"
261#endif
262" e print exception information\n\
263 f flush cache\n\
264 la lookup symbol+offset of specified address\n\
265 ls lookup address of specified symbol\n\
266 lp s [#] lookup address of percpu symbol s for current cpu, or cpu #\n\
267 m examine/change memory\n\
268 mm move a block of memory\n\
269 ms set a block of memory\n\
270 md compare two blocks of memory\n\
271 ml locate a block of memory\n\
272 mz zero a block of memory\n\
273 mi show information about memory allocation\n\
274 p call a procedure\n\
275 P list processes/tasks\n\
276 r print registers\n\
277 s single step\n"
278#ifdef CONFIG_SPU_BASE
279" ss stop execution on all spus\n\
280 sr restore execution on stopped spus\n\
281 sf # dump spu fields for spu # (in hex)\n\
282 sd # dump spu local store for spu # (in hex)\n\
283 sdi # disassemble spu local store for spu # (in hex)\n"
284#endif
285" S print special registers\n\
286 Sa print all SPRs\n\
287 Sr # read SPR #\n\
288 Sw #v write v to SPR #\n\
289 t print backtrace\n\
290 x exit monitor and recover\n\
291 X exit monitor and don't recover\n"
292#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
293" u dump segment table or SLB\n"
294#elif defined(CONFIG_PPC_BOOK3S_32)
295" u dump segment registers\n"
296#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
297" u dump TLB\n"
298#endif
299" U show uptime information\n"
300" ? help\n"
301" # n limit output to n lines per page (for dp, dpa, dl)\n"
302" zr reboot\n"
303" zh halt\n"
304;
305
306#ifdef CONFIG_SECURITY
307static bool xmon_is_locked_down(void)
308{
309 static bool lockdown;
310
311 if (!lockdown) {
312 lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
313 if (lockdown) {
314 printf("xmon: Disabled due to kernel lockdown\n");
315 xmon_is_ro = true;
316 }
317 }
318
319 if (!xmon_is_ro) {
320 xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
321 if (xmon_is_ro)
322 printf("xmon: Read-only due to kernel lockdown\n");
323 }
324
325 return lockdown;
326}
327#else
328static inline bool xmon_is_locked_down(void)
329{
330 return false;
331}
332#endif
333
334static struct pt_regs *xmon_regs;
335
336static inline void sync(void)
337{
338 asm volatile("sync; isync");
339}
340
341static inline void cflush(void *p)
342{
343 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
344}
345
346static inline void cinval(void *p)
347{
348 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
349}
350
351
352
353
354
355
356
357
358
359
360static void write_ciabr(unsigned long ciabr)
361{
362 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
363 return;
364
365 if (cpu_has_feature(CPU_FTR_HVMODE)) {
366 mtspr(SPRN_CIABR, ciabr);
367 return;
368 }
369 plpar_set_ciabr(ciabr);
370}
371
372
373
374
375
376
377
378
379static void set_ciabr(unsigned long addr)
380{
381 addr &= ~CIABR_PRIV;
382
383 if (cpu_has_feature(CPU_FTR_HVMODE))
384 addr |= CIABR_PRIV_HYPER;
385 else
386 addr |= CIABR_PRIV_SUPER;
387 write_ciabr(addr);
388}
389
390
391
392
393
394
395#define SURVEILLANCE_TOKEN 9000
396
397static inline void disable_surveillance(void)
398{
399#ifdef CONFIG_PPC_PSERIES
400
401 static struct rtas_args args;
402
403
404
405
406
407
408
409
410 if (set_indicator_token == RTAS_UNKNOWN_SERVICE)
411 return;
412
413 rtas_call_unlocked(&args, set_indicator_token, 3, 1, NULL,
414 SURVEILLANCE_TOKEN, 0, 0);
415
416#endif
417}
418
419#ifdef CONFIG_SMP
420static int xmon_speaker;
421
422static void get_output_lock(void)
423{
424 int me = smp_processor_id() + 0x100;
425 int last_speaker = 0, prev;
426 long timeout;
427
428 if (xmon_speaker == me)
429 return;
430
431 for (;;) {
432 last_speaker = cmpxchg(&xmon_speaker, 0, me);
433 if (last_speaker == 0)
434 return;
435
436
437
438
439
440 timeout = 10000;
441 while (xmon_speaker == last_speaker) {
442 if (--timeout > 0) {
443 udelay(100);
444 continue;
445 }
446
447
448 prev = cmpxchg(&xmon_speaker, last_speaker, me);
449 if (prev == last_speaker)
450 return;
451 break;
452 }
453 }
454}
455
456static void release_output_lock(void)
457{
458 xmon_speaker = 0;
459}
460
461int cpus_are_in_xmon(void)
462{
463 return !cpumask_empty(&cpus_in_xmon);
464}
465
466static bool wait_for_other_cpus(int ncpus)
467{
468 unsigned long timeout;
469
470
471 for (timeout = 20000; timeout != 0; --timeout) {
472 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
473 return true;
474 udelay(100);
475 barrier();
476 }
477
478 return false;
479}
480#else
481static inline void get_output_lock(void) {}
482static inline void release_output_lock(void) {}
483#endif
484
485static inline int unrecoverable_excp(struct pt_regs *regs)
486{
487#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
488
489 return 0;
490#else
491 return ((regs->msr & MSR_RI) == 0);
492#endif
493}
494
495static void xmon_touch_watchdogs(void)
496{
497 touch_softlockup_watchdog_sync();
498 rcu_cpu_stall_reset();
499 touch_nmi_watchdog();
500}
501
502static int xmon_core(struct pt_regs *regs, volatile int fromipi)
503{
504 volatile int cmd = 0;
505 struct bpt *volatile bp;
506 long recurse_jmp[JMP_BUF_LEN];
507 bool locked_down;
508 unsigned long offset;
509 unsigned long flags;
510#ifdef CONFIG_SMP
511 int cpu;
512 int secondary;
513#endif
514
515 local_irq_save(flags);
516 hard_irq_disable();
517
518 locked_down = xmon_is_locked_down();
519
520 if (!fromipi) {
521 tracing_enabled = tracing_is_on();
522 tracing_off();
523 }
524
525 bp = in_breakpoint_table(regs->nip, &offset);
526 if (bp != NULL) {
527 regs_set_return_ip(regs, bp->address + offset);
528 atomic_dec(&bp->ref_count);
529 }
530
531 remove_cpu_bpts();
532
533#ifdef CONFIG_SMP
534 cpu = smp_processor_id();
535 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
536
537
538
539
540 if (catch_spr_faults)
541 longjmp(bus_error_jmp, 1);
542 get_output_lock();
543 excprint(regs);
544 printf("cpu 0x%x: Exception %lx %s in xmon, "
545 "returning to main loop\n",
546 cpu, regs->trap, getvecname(TRAP(regs)));
547 release_output_lock();
548 longjmp(xmon_fault_jmp[cpu], 1);
549 }
550
551 if (setjmp(recurse_jmp) != 0) {
552 if (!in_xmon || !xmon_gate) {
553 get_output_lock();
554 printf("xmon: WARNING: bad recursive fault "
555 "on cpu 0x%x\n", cpu);
556 release_output_lock();
557 goto waiting;
558 }
559 secondary = !(xmon_taken && cpu == xmon_owner);
560 goto cmdloop;
561 }
562
563 xmon_fault_jmp[cpu] = recurse_jmp;
564
565 bp = NULL;
566 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
567 bp = at_breakpoint(regs->nip);
568 if (bp || unrecoverable_excp(regs))
569 fromipi = 0;
570
571 if (!fromipi) {
572 get_output_lock();
573 if (!locked_down)
574 excprint(regs);
575 if (bp) {
576 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
577 cpu, BP_NUM(bp));
578 xmon_print_symbol(regs->nip, " ", ")\n");
579 }
580 if (unrecoverable_excp(regs))
581 printf("WARNING: exception is not recoverable, "
582 "can't continue\n");
583 release_output_lock();
584 }
585
586 cpumask_set_cpu(cpu, &cpus_in_xmon);
587
588 waiting:
589 secondary = 1;
590 spin_begin();
591 while (secondary && !xmon_gate) {
592 if (in_xmon == 0) {
593 if (fromipi) {
594 spin_end();
595 goto leave;
596 }
597 secondary = test_and_set_bit(0, &in_xmon);
598 }
599 spin_cpu_relax();
600 touch_nmi_watchdog();
601 }
602 spin_end();
603
604 if (!secondary && !xmon_gate) {
605
606
607 int ncpus = num_online_cpus();
608
609 xmon_owner = cpu;
610 mb();
611 if (ncpus > 1) {
612
613
614
615
616
617
618
619 if (TRAP(regs) != INTERRUPT_SYSTEM_RESET || !wait_for_other_cpus(ncpus))
620 smp_send_debugger_break();
621
622 wait_for_other_cpus(ncpus);
623 }
624 remove_bpts();
625 disable_surveillance();
626
627 if (!locked_down) {
628
629 if (bp || TRAP(regs) == INTERRUPT_TRACE)
630 ppc_inst_dump(regs->nip, 1, 0);
631 printf("enter ? for help\n");
632 }
633
634 mb();
635 xmon_gate = 1;
636 barrier();
637 touch_nmi_watchdog();
638 }
639
640 cmdloop:
641 while (in_xmon) {
642 if (secondary) {
643 spin_begin();
644 if (cpu == xmon_owner) {
645 if (!test_and_set_bit(0, &xmon_taken)) {
646 secondary = 0;
647 spin_end();
648 continue;
649 }
650
651 while (cpu == xmon_owner)
652 spin_cpu_relax();
653 }
654 spin_cpu_relax();
655 touch_nmi_watchdog();
656 } else {
657 cmd = 1;
658#ifdef CONFIG_SMP
659 if (xmon_batch)
660 cmd = batch_cmds(regs);
661#endif
662 if (!locked_down && cmd)
663 cmd = cmds(regs);
664 if (locked_down || cmd != 0) {
665
666 insert_bpts();
667 xmon_gate = 0;
668 wmb();
669 in_xmon = 0;
670 break;
671 }
672
673 secondary = 1;
674 }
675 }
676 leave:
677 cpumask_clear_cpu(cpu, &cpus_in_xmon);
678 xmon_fault_jmp[cpu] = NULL;
679#else
680
681 if (in_xmon) {
682 printf("Exception %lx %s in xmon, returning to main loop\n",
683 regs->trap, getvecname(TRAP(regs)));
684 longjmp(xmon_fault_jmp[0], 1);
685 }
686 if (setjmp(recurse_jmp) == 0) {
687 xmon_fault_jmp[0] = recurse_jmp;
688 in_xmon = 1;
689
690 excprint(regs);
691 bp = at_breakpoint(regs->nip);
692 if (bp) {
693 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
694 xmon_print_symbol(regs->nip, " ", ")\n");
695 }
696 if (unrecoverable_excp(regs))
697 printf("WARNING: exception is not recoverable, "
698 "can't continue\n");
699 remove_bpts();
700 disable_surveillance();
701 if (!locked_down) {
702
703 if (bp || TRAP(regs) == INTERRUPT_TRACE)
704 ppc_inst_dump(regs->nip, 1, 0);
705 printf("enter ? for help\n");
706 }
707 }
708
709 if (!locked_down)
710 cmd = cmds(regs);
711
712 insert_bpts();
713 in_xmon = 0;
714#endif
715
716#ifdef CONFIG_BOOKE
717 if (regs->msr & MSR_DE) {
718 bp = at_breakpoint(regs->nip);
719 if (bp != NULL) {
720 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
721 atomic_inc(&bp->ref_count);
722 }
723 }
724#else
725 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
726 bp = at_breakpoint(regs->nip);
727 if (bp != NULL) {
728 int stepped = emulate_step(regs, ppc_inst_read(bp->instr));
729 if (stepped == 0) {
730 regs_set_return_ip(regs, (unsigned long) &bp->instr[0]);
731 atomic_inc(&bp->ref_count);
732 } else if (stepped < 0) {
733 printf("Couldn't single-step %s instruction\n",
734 IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd");
735 }
736 }
737 }
738#endif
739 if (locked_down)
740 clear_all_bpt();
741 else
742 insert_cpu_bpts();
743
744 xmon_touch_watchdogs();
745 local_irq_restore(flags);
746
747 return cmd != 'X' && cmd != EOF;
748}
749
750int xmon(struct pt_regs *excp)
751{
752 struct pt_regs regs;
753
754 if (excp == NULL) {
755 ppc_save_regs(®s);
756 excp = ®s;
757 }
758
759 return xmon_core(excp, 0);
760}
761EXPORT_SYMBOL(xmon);
762
763irqreturn_t xmon_irq(int irq, void *d)
764{
765 unsigned long flags;
766 local_irq_save(flags);
767 printf("Keyboard interrupt\n");
768 xmon(get_irq_regs());
769 local_irq_restore(flags);
770 return IRQ_HANDLED;
771}
772
773static int xmon_bpt(struct pt_regs *regs)
774{
775 struct bpt *bp;
776 unsigned long offset;
777
778 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
779 return 0;
780
781
782 bp = in_breakpoint_table(regs->nip, &offset);
783 if (bp != NULL && (offset == 4 || offset == 8)) {
784 regs_set_return_ip(regs, bp->address + offset);
785 atomic_dec(&bp->ref_count);
786 return 1;
787 }
788
789
790 bp = at_breakpoint(regs->nip);
791 if (!bp)
792 return 0;
793
794 xmon_core(regs, 0);
795
796 return 1;
797}
798
799static int xmon_sstep(struct pt_regs *regs)
800{
801 if (user_mode(regs))
802 return 0;
803 xmon_core(regs, 0);
804 return 1;
805}
806
807static int xmon_break_match(struct pt_regs *regs)
808{
809 int i;
810
811 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
812 return 0;
813 for (i = 0; i < nr_wp_slots(); i++) {
814 if (dabr[i].enabled)
815 goto found;
816 }
817 return 0;
818
819found:
820 xmon_core(regs, 0);
821 return 1;
822}
823
824static int xmon_iabr_match(struct pt_regs *regs)
825{
826 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
827 return 0;
828 if (iabr == NULL)
829 return 0;
830 xmon_core(regs, 0);
831 return 1;
832}
833
834static int xmon_ipi(struct pt_regs *regs)
835{
836#ifdef CONFIG_SMP
837 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
838 xmon_core(regs, 1);
839#endif
840 return 0;
841}
842
843static int xmon_fault_handler(struct pt_regs *regs)
844{
845 struct bpt *bp;
846 unsigned long offset;
847
848 if (in_xmon && catch_memory_errors)
849 handle_fault(regs);
850
851 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
852 bp = in_breakpoint_table(regs->nip, &offset);
853 if (bp != NULL) {
854 regs_set_return_ip(regs, bp->address + offset);
855 atomic_dec(&bp->ref_count);
856 }
857 }
858
859 return 0;
860}
861
862
863static inline void force_enable_xmon(void)
864{
865
866 if (!xmon_on) {
867 printf("xmon: Enabling debugger hooks\n");
868 xmon_on = 1;
869 }
870}
871
872static struct bpt *at_breakpoint(unsigned long pc)
873{
874 int i;
875 struct bpt *volatile bp;
876
877 bp = bpts;
878 for (i = 0; i < NBPTS; ++i, ++bp)
879 if (bp->enabled && pc == bp->address)
880 return bp;
881 return NULL;
882}
883
884static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
885{
886 unsigned long off;
887
888 off = nip - (unsigned long)bpt_table;
889 if (off >= sizeof(bpt_table))
890 return NULL;
891 *offp = off & (BPT_SIZE - 1);
892 if (off & 3)
893 return NULL;
894 return bpts + (off / BPT_SIZE);
895}
896
897static struct bpt *new_breakpoint(unsigned long a)
898{
899 struct bpt *bp;
900
901 a &= ~3UL;
902 bp = at_breakpoint(a);
903 if (bp)
904 return bp;
905
906 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
907 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
908 bp->address = a;
909 bp->instr = (void *)(bpt_table + ((bp - bpts) * BPT_WORDS));
910 return bp;
911 }
912 }
913
914 printf("Sorry, no free breakpoints. Please clear one first.\n");
915 return NULL;
916}
917
918static void insert_bpts(void)
919{
920 int i;
921 struct ppc_inst instr, instr2;
922 struct bpt *bp, *bp2;
923
924 bp = bpts;
925 for (i = 0; i < NBPTS; ++i, ++bp) {
926 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
927 continue;
928 if (!mread_instr(bp->address, &instr)) {
929 printf("Couldn't read instruction at %lx, "
930 "disabling breakpoint there\n", bp->address);
931 bp->enabled = 0;
932 continue;
933 }
934 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
935 printf("Breakpoint at %lx is on an mtmsrd or rfid "
936 "instruction, disabling it\n", bp->address);
937 bp->enabled = 0;
938 continue;
939 }
940
941
942
943
944 if (mread_instr(bp->address - 4, &instr2) == 8) {
945 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
946 bp->address);
947 bp->enabled = 0;
948 continue;
949 }
950
951
952
953
954
955 bp2 = at_breakpoint(bp->address - 4);
956 if (bp2 && ppc_inst_prefixed(ppc_inst_read(bp2->instr))) {
957 printf("Breakpoint at %lx is on the second word of a prefixed instruction, disabling it\n",
958 bp->address);
959 bp->enabled = 0;
960 continue;
961 }
962
963 patch_instruction(bp->instr, instr);
964 patch_instruction(ppc_inst_next(bp->instr, bp->instr),
965 ppc_inst(bpinstr));
966 if (bp->enabled & BP_CIABR)
967 continue;
968 if (patch_instruction((u32 *)bp->address,
969 ppc_inst(bpinstr)) != 0) {
970 printf("Couldn't write instruction at %lx, "
971 "disabling breakpoint there\n", bp->address);
972 bp->enabled &= ~BP_TRAP;
973 continue;
974 }
975 }
976}
977
978static void insert_cpu_bpts(void)
979{
980 int i;
981 struct arch_hw_breakpoint brk;
982
983 for (i = 0; i < nr_wp_slots(); i++) {
984 if (dabr[i].enabled) {
985 brk.address = dabr[i].address;
986 brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
987 brk.len = 8;
988 brk.hw_len = 8;
989 __set_breakpoint(i, &brk);
990 }
991 }
992
993 if (iabr)
994 set_ciabr(iabr->address);
995}
996
997static void remove_bpts(void)
998{
999 int i;
1000 struct bpt *bp;
1001 struct ppc_inst instr;
1002
1003 bp = bpts;
1004 for (i = 0; i < NBPTS; ++i, ++bp) {
1005 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
1006 continue;
1007 if (mread_instr(bp->address, &instr)
1008 && ppc_inst_equal(instr, ppc_inst(bpinstr))
1009 && patch_instruction(
1010 (u32 *)bp->address, ppc_inst_read(bp->instr)) != 0)
1011 printf("Couldn't remove breakpoint at %lx\n",
1012 bp->address);
1013 }
1014}
1015
1016static void remove_cpu_bpts(void)
1017{
1018 hw_breakpoint_disable();
1019 write_ciabr(0);
1020}
1021
1022
1023static void
1024show_uptime(void)
1025{
1026 struct timespec64 uptime;
1027
1028 if (setjmp(bus_error_jmp) == 0) {
1029 catch_memory_errors = 1;
1030 sync();
1031
1032 ktime_get_coarse_boottime_ts64(&uptime);
1033 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
1034 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
1035
1036 sync();
1037 __delay(200); \
1038 }
1039 catch_memory_errors = 0;
1040}
1041
1042static void set_lpp_cmd(void)
1043{
1044 unsigned long lpp;
1045
1046 if (!scanhex(&lpp)) {
1047 printf("Invalid number.\n");
1048 lpp = 0;
1049 }
1050 xmon_set_pagination_lpp(lpp);
1051}
1052
1053static char *last_cmd;
1054
1055static int
1056cmds(struct pt_regs *excp)
1057{
1058 int cmd = 0;
1059
1060 last_cmd = NULL;
1061 xmon_regs = excp;
1062
1063 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1064
1065 for(;;) {
1066#ifdef CONFIG_SMP
1067 printf("%x:", smp_processor_id());
1068#endif
1069 printf("mon> ");
1070 flush_input();
1071 termch = 0;
1072 cmd = skipbl();
1073 if( cmd == '\n' ) {
1074 if (last_cmd == NULL)
1075 continue;
1076 take_input(last_cmd);
1077 last_cmd = NULL;
1078 cmd = inchar();
1079 }
1080 switch (cmd) {
1081 case 'm':
1082 cmd = inchar();
1083 switch (cmd) {
1084 case 'm':
1085 case 's':
1086 case 'd':
1087 memops(cmd);
1088 break;
1089 case 'l':
1090 memlocate();
1091 break;
1092 case 'z':
1093 if (xmon_is_ro) {
1094 printf(xmon_ro_msg);
1095 break;
1096 }
1097 memzcan();
1098 break;
1099 case 'i':
1100 show_mem(0, NULL);
1101 break;
1102 default:
1103 termch = cmd;
1104 memex();
1105 }
1106 break;
1107 case 'd':
1108 dump();
1109 break;
1110 case 'l':
1111 symbol_lookup();
1112 break;
1113 case 'r':
1114 prregs(excp);
1115 break;
1116 case 'e':
1117 excprint(excp);
1118 break;
1119 case 'S':
1120 super_regs();
1121 break;
1122 case 't':
1123 backtrace(excp);
1124 break;
1125 case 'f':
1126 cacheflush();
1127 break;
1128 case 's':
1129 if (do_spu_cmd() == 0)
1130 break;
1131 if (do_step(excp))
1132 return cmd;
1133 break;
1134 case 'x':
1135 case 'X':
1136 if (tracing_enabled)
1137 tracing_on();
1138 return cmd;
1139 case EOF:
1140 printf(" <no input ...>\n");
1141 mdelay(2000);
1142 return cmd;
1143 case '?':
1144 xmon_puts(help_string);
1145 break;
1146 case '#':
1147 set_lpp_cmd();
1148 break;
1149 case 'b':
1150 bpt_cmds();
1151 break;
1152 case 'C':
1153 csum();
1154 break;
1155 case 'c':
1156 if (cpu_cmd())
1157 return 0;
1158 break;
1159 case 'z':
1160 bootcmds();
1161 break;
1162 case 'p':
1163 if (xmon_is_ro) {
1164 printf(xmon_ro_msg);
1165 break;
1166 }
1167 proccall();
1168 break;
1169 case 'P':
1170 show_tasks();
1171 break;
1172#ifdef CONFIG_PPC_BOOK3S
1173 case 'u':
1174 dump_segments();
1175 break;
1176#elif defined(CONFIG_44x)
1177 case 'u':
1178 dump_tlb_44x();
1179 break;
1180#elif defined(CONFIG_PPC_BOOK3E)
1181 case 'u':
1182 dump_tlb_book3e();
1183 break;
1184#endif
1185 case 'U':
1186 show_uptime();
1187 break;
1188 default:
1189 printf("Unrecognized command: ");
1190 do {
1191 if (' ' < cmd && cmd <= '~')
1192 putchar(cmd);
1193 else
1194 printf("\\x%x", cmd);
1195 cmd = inchar();
1196 } while (cmd != '\n');
1197 printf(" (type ? for help)\n");
1198 break;
1199 }
1200 }
1201}
1202
1203#ifdef CONFIG_BOOKE
1204static int do_step(struct pt_regs *regs)
1205{
1206 regs_set_return_msr(regs, regs->msr | MSR_DE);
1207 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1208 return 1;
1209}
1210#else
1211
1212
1213
1214
1215static int do_step(struct pt_regs *regs)
1216{
1217 struct ppc_inst instr;
1218 int stepped;
1219
1220 force_enable_xmon();
1221
1222 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1223 if (mread_instr(regs->nip, &instr)) {
1224 stepped = emulate_step(regs, instr);
1225 if (stepped < 0) {
1226 printf("Couldn't single-step %s instruction\n",
1227 (IS_RFID(instr)? "rfid": "mtmsrd"));
1228 return 0;
1229 }
1230 if (stepped > 0) {
1231 set_trap(regs, 0xd00);
1232 printf("stepped to ");
1233 xmon_print_symbol(regs->nip, " ", "\n");
1234 ppc_inst_dump(regs->nip, 1, 0);
1235 return 0;
1236 }
1237 }
1238 }
1239 regs_set_return_msr(regs, regs->msr | MSR_SE);
1240 return 1;
1241}
1242#endif
1243
1244static void bootcmds(void)
1245{
1246 char tmp[64];
1247 int cmd;
1248
1249 cmd = inchar();
1250 if (cmd == 'r') {
1251 getstring(tmp, 64);
1252 ppc_md.restart(tmp);
1253 } else if (cmd == 'h') {
1254 ppc_md.halt();
1255 } else if (cmd == 'p') {
1256 if (pm_power_off)
1257 pm_power_off();
1258 }
1259}
1260
1261#ifdef CONFIG_SMP
1262static int xmon_switch_cpu(unsigned long cpu)
1263{
1264 int timeout;
1265
1266 xmon_taken = 0;
1267 mb();
1268 xmon_owner = cpu;
1269 timeout = 10000000;
1270 while (!xmon_taken) {
1271 if (--timeout == 0) {
1272 if (test_and_set_bit(0, &xmon_taken))
1273 break;
1274
1275 mb();
1276 xmon_owner = smp_processor_id();
1277 printf("cpu 0x%lx didn't take control\n", cpu);
1278 return 0;
1279 }
1280 barrier();
1281 }
1282 return 1;
1283}
1284
1285static int xmon_batch_next_cpu(void)
1286{
1287 unsigned long cpu;
1288
1289 while (!cpumask_empty(&xmon_batch_cpus)) {
1290 cpu = cpumask_next_wrap(smp_processor_id(), &xmon_batch_cpus,
1291 xmon_batch_start_cpu, true);
1292 if (cpu == nr_cpumask_bits)
1293 break;
1294 if (xmon_batch_start_cpu == -1)
1295 xmon_batch_start_cpu = cpu;
1296 if (xmon_switch_cpu(cpu))
1297 return 0;
1298 cpumask_clear_cpu(cpu, &xmon_batch_cpus);
1299 }
1300
1301 xmon_batch = 0;
1302 printf("%x:mon> \n", smp_processor_id());
1303 return 1;
1304}
1305
1306static int batch_cmds(struct pt_regs *excp)
1307{
1308 int cmd;
1309
1310
1311 cmd = xmon_batch;
1312 termch = '\n';
1313
1314 last_cmd = NULL;
1315 xmon_regs = excp;
1316
1317 printf("%x:", smp_processor_id());
1318 printf("mon> ");
1319 printf("%c\n", (char)cmd);
1320
1321 switch (cmd) {
1322 case 'r':
1323 prregs(excp);
1324 break;
1325 case 'S':
1326 super_regs();
1327 break;
1328 case 't':
1329 backtrace(excp);
1330 break;
1331 }
1332
1333 cpumask_clear_cpu(smp_processor_id(), &xmon_batch_cpus);
1334
1335 return xmon_batch_next_cpu();
1336}
1337
1338static int cpu_cmd(void)
1339{
1340 unsigned long cpu, first_cpu, last_cpu;
1341
1342 cpu = skipbl();
1343 if (cpu == '#') {
1344 xmon_batch = skipbl();
1345 if (xmon_batch) {
1346 switch (xmon_batch) {
1347 case 'r':
1348 case 'S':
1349 case 't':
1350 cpumask_copy(&xmon_batch_cpus, &cpus_in_xmon);
1351 if (cpumask_weight(&xmon_batch_cpus) <= 1) {
1352 printf("There are no other cpus in xmon\n");
1353 break;
1354 }
1355 xmon_batch_start_cpu = -1;
1356 if (!xmon_batch_next_cpu())
1357 return 1;
1358 break;
1359 default:
1360 printf("c# only supports 'r', 'S' and 't' commands\n");
1361 }
1362 xmon_batch = 0;
1363 return 0;
1364 }
1365 }
1366 termch = cpu;
1367
1368 if (!scanhex(&cpu)) {
1369
1370 printf("cpus stopped:");
1371 last_cpu = first_cpu = NR_CPUS;
1372 for_each_possible_cpu(cpu) {
1373 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1374 if (cpu == last_cpu + 1) {
1375 last_cpu = cpu;
1376 } else {
1377 if (last_cpu != first_cpu)
1378 printf("-0x%lx", last_cpu);
1379 last_cpu = first_cpu = cpu;
1380 printf(" 0x%lx", cpu);
1381 }
1382 }
1383 }
1384 if (last_cpu != first_cpu)
1385 printf("-0x%lx", last_cpu);
1386 printf("\n");
1387 return 0;
1388 }
1389
1390 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1391 printf("cpu 0x%lx isn't in xmon\n", cpu);
1392#ifdef CONFIG_PPC64
1393 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1394 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1395#endif
1396 return 0;
1397 }
1398
1399 return xmon_switch_cpu(cpu);
1400}
1401#else
1402static int cpu_cmd(void)
1403{
1404 return 0;
1405}
1406#endif
1407
1408static unsigned short fcstab[256] = {
1409 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1410 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1411 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1412 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1413 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1414 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1415 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1416 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1417 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1418 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1419 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1420 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1421 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1422 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1423 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1424 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1425 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1426 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1427 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1428 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1429 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1430 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1431 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1432 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1433 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1434 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1435 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1436 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1437 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1438 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1439 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1440 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1441};
1442
1443#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1444
1445static void
1446csum(void)
1447{
1448 unsigned int i;
1449 unsigned short fcs;
1450 unsigned char v;
1451
1452 if (!scanhex(&adrs))
1453 return;
1454 if (!scanhex(&ncsum))
1455 return;
1456 fcs = 0xffff;
1457 for (i = 0; i < ncsum; ++i) {
1458 if (mread(adrs+i, &v, 1) == 0) {
1459 printf("csum stopped at "REG"\n", adrs+i);
1460 break;
1461 }
1462 fcs = FCS(fcs, v);
1463 }
1464 printf("%x\n", fcs);
1465}
1466
1467
1468
1469
1470static long check_bp_loc(unsigned long addr)
1471{
1472 struct ppc_inst instr;
1473
1474 addr &= ~3;
1475 if (!is_kernel_addr(addr)) {
1476 printf("Breakpoints may only be placed at kernel addresses\n");
1477 return 0;
1478 }
1479 if (!mread_instr(addr, &instr)) {
1480 printf("Can't read instruction at address %lx\n", addr);
1481 return 0;
1482 }
1483 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1484 printf("Breakpoints may not be placed on mtmsrd or rfid "
1485 "instructions\n");
1486 return 0;
1487 }
1488 return 1;
1489}
1490
1491static int find_free_data_bpt(void)
1492{
1493 int i;
1494
1495 for (i = 0; i < nr_wp_slots(); i++) {
1496 if (!dabr[i].enabled)
1497 return i;
1498 }
1499 printf("Couldn't find free breakpoint register\n");
1500 return -1;
1501}
1502
1503static void print_data_bpts(void)
1504{
1505 int i;
1506
1507 for (i = 0; i < nr_wp_slots(); i++) {
1508 if (!dabr[i].enabled)
1509 continue;
1510
1511 printf(" data "REG" [", dabr[i].address);
1512 if (dabr[i].enabled & 1)
1513 printf("r");
1514 if (dabr[i].enabled & 2)
1515 printf("w");
1516 printf("]\n");
1517 }
1518}
1519
1520static char *breakpoint_help_string =
1521 "Breakpoint command usage:\n"
1522 "b show breakpoints\n"
1523 "b <addr> [cnt] set breakpoint at given instr addr\n"
1524 "bc clear all breakpoints\n"
1525 "bc <n/addr> clear breakpoint number n or at addr\n"
1526 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1527 "bd <addr> [cnt] set hardware data breakpoint\n"
1528 "";
1529
1530static void
1531bpt_cmds(void)
1532{
1533 int cmd;
1534 unsigned long a;
1535 int i;
1536 struct bpt *bp;
1537
1538 cmd = inchar();
1539
1540 switch (cmd) {
1541 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1542 int mode;
1543 case 'd':
1544 if (xmon_is_ro) {
1545 printf(xmon_ro_msg);
1546 break;
1547 }
1548 if (!ppc_breakpoint_available()) {
1549 printf("Hardware data breakpoint not supported on this cpu\n");
1550 break;
1551 }
1552 i = find_free_data_bpt();
1553 if (i < 0)
1554 break;
1555 mode = 7;
1556 cmd = inchar();
1557 if (cmd == 'r')
1558 mode = 5;
1559 else if (cmd == 'w')
1560 mode = 6;
1561 else
1562 termch = cmd;
1563 dabr[i].address = 0;
1564 dabr[i].enabled = 0;
1565 if (scanhex(&dabr[i].address)) {
1566 if (!is_kernel_addr(dabr[i].address)) {
1567 printf(badaddr);
1568 break;
1569 }
1570 dabr[i].address &= ~HW_BRK_TYPE_DABR;
1571 dabr[i].enabled = mode | BP_DABR;
1572 }
1573
1574 force_enable_xmon();
1575 break;
1576
1577 case 'i':
1578 if (xmon_is_ro) {
1579 printf(xmon_ro_msg);
1580 break;
1581 }
1582 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1583 printf("Hardware instruction breakpoint "
1584 "not supported on this cpu\n");
1585 break;
1586 }
1587 if (iabr) {
1588 iabr->enabled &= ~BP_CIABR;
1589 iabr = NULL;
1590 }
1591 if (!scanhex(&a))
1592 break;
1593 if (!check_bp_loc(a))
1594 break;
1595 bp = new_breakpoint(a);
1596 if (bp != NULL) {
1597 bp->enabled |= BP_CIABR;
1598 iabr = bp;
1599 force_enable_xmon();
1600 }
1601 break;
1602
1603 case 'c':
1604 if (!scanhex(&a)) {
1605
1606 for (i = 0; i < NBPTS; ++i)
1607 bpts[i].enabled = 0;
1608 iabr = NULL;
1609 for (i = 0; i < nr_wp_slots(); i++)
1610 dabr[i].enabled = 0;
1611
1612 printf("All breakpoints cleared\n");
1613 break;
1614 }
1615
1616 if (a <= NBPTS && a >= 1) {
1617
1618 bp = &bpts[a-1];
1619 } else {
1620
1621 bp = at_breakpoint(a);
1622 if (bp == NULL) {
1623 printf("No breakpoint at %lx\n", a);
1624 break;
1625 }
1626 }
1627
1628 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1629 xmon_print_symbol(bp->address, " ", ")\n");
1630 bp->enabled = 0;
1631 break;
1632
1633 default:
1634 termch = cmd;
1635 cmd = skipbl();
1636 if (cmd == '?') {
1637 printf(breakpoint_help_string);
1638 break;
1639 }
1640 termch = cmd;
1641
1642 if (xmon_is_ro || !scanhex(&a)) {
1643
1644 printf(" type address\n");
1645 print_data_bpts();
1646 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1647 if (!bp->enabled)
1648 continue;
1649 printf("%tx %s ", BP_NUM(bp),
1650 (bp->enabled & BP_CIABR) ? "inst": "trap");
1651 xmon_print_symbol(bp->address, " ", "\n");
1652 }
1653 break;
1654 }
1655
1656 if (!check_bp_loc(a))
1657 break;
1658 bp = new_breakpoint(a);
1659 if (bp != NULL) {
1660 bp->enabled |= BP_TRAP;
1661 force_enable_xmon();
1662 }
1663 break;
1664 }
1665}
1666
1667
1668static
1669const char *getvecname(unsigned long vec)
1670{
1671 char *ret;
1672
1673 switch (vec) {
1674 case 0x100: ret = "(System Reset)"; break;
1675 case 0x200: ret = "(Machine Check)"; break;
1676 case 0x300: ret = "(Data Access)"; break;
1677 case 0x380:
1678 if (radix_enabled())
1679 ret = "(Data Access Out of Range)";
1680 else
1681 ret = "(Data SLB Access)";
1682 break;
1683 case 0x400: ret = "(Instruction Access)"; break;
1684 case 0x480:
1685 if (radix_enabled())
1686 ret = "(Instruction Access Out of Range)";
1687 else
1688 ret = "(Instruction SLB Access)";
1689 break;
1690 case 0x500: ret = "(Hardware Interrupt)"; break;
1691 case 0x600: ret = "(Alignment)"; break;
1692 case 0x700: ret = "(Program Check)"; break;
1693 case 0x800: ret = "(FPU Unavailable)"; break;
1694 case 0x900: ret = "(Decrementer)"; break;
1695 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1696 case 0xa00: ret = "(Doorbell)"; break;
1697 case 0xc00: ret = "(System Call)"; break;
1698 case 0xd00: ret = "(Single Step)"; break;
1699 case 0xe40: ret = "(Emulation Assist)"; break;
1700 case 0xe60: ret = "(HMI)"; break;
1701 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1702 case 0xf00: ret = "(Performance Monitor)"; break;
1703 case 0xf20: ret = "(Altivec Unavailable)"; break;
1704 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1705 case 0x1500: ret = "(Denormalisation)"; break;
1706 case 0x1700: ret = "(Altivec Assist)"; break;
1707 case 0x3000: ret = "(System Call Vectored)"; break;
1708 default: ret = "";
1709 }
1710 return ret;
1711}
1712
1713static void get_function_bounds(unsigned long pc, unsigned long *startp,
1714 unsigned long *endp)
1715{
1716 unsigned long size, offset;
1717 const char *name;
1718
1719 *startp = *endp = 0;
1720 if (pc == 0)
1721 return;
1722 if (setjmp(bus_error_jmp) == 0) {
1723 catch_memory_errors = 1;
1724 sync();
1725 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1726 if (name != NULL) {
1727 *startp = pc - offset;
1728 *endp = pc - offset + size;
1729 }
1730 sync();
1731 }
1732 catch_memory_errors = 0;
1733}
1734
1735#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1736#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1737
1738static void xmon_show_stack(unsigned long sp, unsigned long lr,
1739 unsigned long pc)
1740{
1741 int max_to_print = 64;
1742 unsigned long ip;
1743 unsigned long newsp;
1744 unsigned long marker;
1745 struct pt_regs regs;
1746
1747 while (max_to_print--) {
1748 if (!is_kernel_addr(sp)) {
1749 if (sp != 0)
1750 printf("SP (%lx) is in userspace\n", sp);
1751 break;
1752 }
1753
1754 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1755 || !mread(sp, &newsp, sizeof(unsigned long))) {
1756 printf("Couldn't read stack frame at %lx\n", sp);
1757 break;
1758 }
1759
1760
1761
1762
1763
1764
1765 if ((pc | lr) != 0) {
1766 unsigned long fnstart, fnend;
1767 unsigned long nextip;
1768 int printip = 1;
1769
1770 get_function_bounds(pc, &fnstart, &fnend);
1771 nextip = 0;
1772 if (newsp > sp)
1773 mread(newsp + LRSAVE_OFFSET, &nextip,
1774 sizeof(unsigned long));
1775 if (lr == ip) {
1776 if (!is_kernel_addr(lr)
1777 || (fnstart <= lr && lr < fnend))
1778 printip = 0;
1779 } else if (lr == nextip) {
1780 printip = 0;
1781 } else if (is_kernel_addr(lr)
1782 && !(fnstart <= lr && lr < fnend)) {
1783 printf("[link register ] ");
1784 xmon_print_symbol(lr, " ", "\n");
1785 }
1786 if (printip) {
1787 printf("["REG"] ", sp);
1788 xmon_print_symbol(ip, " ", " (unreliable)\n");
1789 }
1790 pc = lr = 0;
1791
1792 } else {
1793 printf("["REG"] ", sp);
1794 xmon_print_symbol(ip, " ", "\n");
1795 }
1796
1797
1798
1799 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1800 && marker == STACK_FRAME_REGS_MARKER) {
1801 if (mread(sp + STACK_FRAME_OVERHEAD, ®s, sizeof(regs))
1802 != sizeof(regs)) {
1803 printf("Couldn't read registers at %lx\n",
1804 sp + STACK_FRAME_OVERHEAD);
1805 break;
1806 }
1807 printf("--- Exception: %lx %s at ", regs.trap,
1808 getvecname(TRAP(®s)));
1809 pc = regs.nip;
1810 lr = regs.link;
1811 xmon_print_symbol(pc, " ", "\n");
1812 }
1813
1814 if (newsp == 0)
1815 break;
1816
1817 sp = newsp;
1818 }
1819}
1820
1821static void backtrace(struct pt_regs *excp)
1822{
1823 unsigned long sp;
1824
1825 if (scanhex(&sp))
1826 xmon_show_stack(sp, 0, 0);
1827 else
1828 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1829 scannl();
1830}
1831
1832static void print_bug_trap(struct pt_regs *regs)
1833{
1834#ifdef CONFIG_BUG
1835 const struct bug_entry *bug;
1836 unsigned long addr;
1837
1838 if (regs->msr & MSR_PR)
1839 return;
1840 addr = regs->nip;
1841 if (!is_kernel_addr(addr))
1842 return;
1843 bug = find_bug(regs->nip);
1844 if (bug == NULL)
1845 return;
1846 if (is_warning_bug(bug))
1847 return;
1848
1849#ifdef CONFIG_DEBUG_BUGVERBOSE
1850 printf("kernel BUG at %s:%u!\n",
1851 (char *)bug + bug->file_disp, bug->line);
1852#else
1853 printf("kernel BUG at %px!\n", (void *)bug + bug->bug_addr_disp);
1854#endif
1855#endif
1856}
1857
1858static void excprint(struct pt_regs *fp)
1859{
1860 unsigned long trap;
1861
1862#ifdef CONFIG_SMP
1863 printf("cpu 0x%x: ", smp_processor_id());
1864#endif
1865
1866 trap = TRAP(fp);
1867 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1868 printf(" pc: ");
1869 xmon_print_symbol(fp->nip, ": ", "\n");
1870
1871 printf(" lr: ");
1872 xmon_print_symbol(fp->link, ": ", "\n");
1873
1874 printf(" sp: %lx\n", fp->gpr[1]);
1875 printf(" msr: %lx\n", fp->msr);
1876
1877 if (trap == INTERRUPT_DATA_STORAGE ||
1878 trap == INTERRUPT_DATA_SEGMENT ||
1879 trap == INTERRUPT_ALIGNMENT ||
1880 trap == INTERRUPT_MACHINE_CHECK) {
1881 printf(" dar: %lx\n", fp->dar);
1882 if (trap != INTERRUPT_DATA_SEGMENT)
1883 printf(" dsisr: %lx\n", fp->dsisr);
1884 }
1885
1886 printf(" current = 0x%px\n", current);
1887#ifdef CONFIG_PPC64
1888 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
1889 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
1890#endif
1891 if (current) {
1892 printf(" pid = %d, comm = %s\n",
1893 current->pid, current->comm);
1894 }
1895
1896 if (trap == INTERRUPT_PROGRAM)
1897 print_bug_trap(fp);
1898
1899 printf(linux_banner);
1900}
1901
1902static void prregs(struct pt_regs *fp)
1903{
1904 int n, trap;
1905 unsigned long base;
1906 struct pt_regs regs;
1907
1908 if (scanhex(&base)) {
1909 if (setjmp(bus_error_jmp) == 0) {
1910 catch_memory_errors = 1;
1911 sync();
1912 regs = *(struct pt_regs *)base;
1913 sync();
1914 __delay(200);
1915 } else {
1916 catch_memory_errors = 0;
1917 printf("*** Error reading registers from "REG"\n",
1918 base);
1919 return;
1920 }
1921 catch_memory_errors = 0;
1922 fp = ®s;
1923 }
1924
1925#ifdef CONFIG_PPC64
1926#define R_PER_LINE 2
1927#else
1928#define R_PER_LINE 4
1929#endif
1930
1931 for (n = 0; n < 32; ++n) {
1932 printf("R%.2d = "REG"%s", n, fp->gpr[n],
1933 (n % R_PER_LINE) == R_PER_LINE - 1 ? "\n" : " ");
1934 }
1935
1936 printf("pc = ");
1937 xmon_print_symbol(fp->nip, " ", "\n");
1938 if (!trap_is_syscall(fp) && cpu_has_feature(CPU_FTR_CFAR)) {
1939 printf("cfar= ");
1940 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1941 }
1942 printf("lr = ");
1943 xmon_print_symbol(fp->link, " ", "\n");
1944 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1945 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1946 fp->ctr, fp->xer, fp->trap);
1947 trap = TRAP(fp);
1948 if (trap == INTERRUPT_DATA_STORAGE ||
1949 trap == INTERRUPT_DATA_SEGMENT ||
1950 trap == INTERRUPT_ALIGNMENT)
1951 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1952}
1953
1954static void cacheflush(void)
1955{
1956 int cmd;
1957 unsigned long nflush;
1958
1959 cmd = inchar();
1960 if (cmd != 'i')
1961 termch = cmd;
1962 scanhex((void *)&adrs);
1963 if (termch != '\n')
1964 termch = 0;
1965 nflush = 1;
1966 scanhex(&nflush);
1967 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1968 if (setjmp(bus_error_jmp) == 0) {
1969 catch_memory_errors = 1;
1970 sync();
1971
1972 if (cmd != 'i' || IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
1973 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1974 cflush((void *) adrs);
1975 } else {
1976 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1977 cinval((void *) adrs);
1978 }
1979 sync();
1980
1981 __delay(200);
1982 }
1983 catch_memory_errors = 0;
1984}
1985
1986extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1987extern void xmon_mtspr(int spr, unsigned long value);
1988
1989static int
1990read_spr(int n, unsigned long *vp)
1991{
1992 unsigned long ret = -1UL;
1993 int ok = 0;
1994
1995 if (setjmp(bus_error_jmp) == 0) {
1996 catch_spr_faults = 1;
1997 sync();
1998
1999 ret = xmon_mfspr(n, *vp);
2000
2001 sync();
2002 *vp = ret;
2003 ok = 1;
2004 }
2005 catch_spr_faults = 0;
2006
2007 return ok;
2008}
2009
2010static void
2011write_spr(int n, unsigned long val)
2012{
2013 if (xmon_is_ro) {
2014 printf(xmon_ro_msg);
2015 return;
2016 }
2017
2018 if (setjmp(bus_error_jmp) == 0) {
2019 catch_spr_faults = 1;
2020 sync();
2021
2022 xmon_mtspr(n, val);
2023
2024 sync();
2025 } else {
2026 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
2027 }
2028 catch_spr_faults = 0;
2029}
2030
2031static void dump_206_sprs(void)
2032{
2033#ifdef CONFIG_PPC64
2034 if (!cpu_has_feature(CPU_FTR_ARCH_206))
2035 return;
2036
2037
2038
2039 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
2040 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
2041 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
2042 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
2043 printf("amr = %.16lx uamor = %.16lx\n",
2044 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
2045
2046 if (!(mfmsr() & MSR_HV))
2047 return;
2048
2049 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
2050 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
2051 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
2052 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
2053 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
2054 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
2055 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
2056 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
2057 printf("dabr = %.16lx dabrx = %.16lx\n",
2058 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
2059#endif
2060}
2061
2062static void dump_207_sprs(void)
2063{
2064#ifdef CONFIG_PPC64
2065 unsigned long msr;
2066
2067 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
2068 return;
2069
2070 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
2071 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
2072
2073 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
2074 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
2075
2076 msr = mfmsr();
2077 if (msr & MSR_TM) {
2078
2079 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
2080 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
2081 mfspr(SPRN_TEXASR));
2082 }
2083
2084 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
2085 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
2086 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
2087 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
2088 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
2089 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
2090 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
2091 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
2092 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
2093 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
2094 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
2095 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
2096
2097 if (!(msr & MSR_HV))
2098 return;
2099
2100 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
2101 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
2102 printf("dawr0 = %.16lx dawrx0 = %.16lx\n",
2103 mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0));
2104 if (nr_wp_slots() > 1) {
2105 printf("dawr1 = %.16lx dawrx1 = %.16lx\n",
2106 mfspr(SPRN_DAWR1), mfspr(SPRN_DAWRX1));
2107 }
2108 printf("ciabr = %.16lx\n", mfspr(SPRN_CIABR));
2109#endif
2110}
2111
2112static void dump_300_sprs(void)
2113{
2114#ifdef CONFIG_PPC64
2115 bool hv = mfmsr() & MSR_HV;
2116
2117 if (!cpu_has_feature(CPU_FTR_ARCH_300))
2118 return;
2119
2120 printf("pidr = %.16lx tidr = %.16lx\n",
2121 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
2122 printf("psscr = %.16lx\n",
2123 hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
2124
2125 if (!hv)
2126 return;
2127
2128 printf("ptcr = %.16lx asdr = %.16lx\n",
2129 mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
2130#endif
2131}
2132
2133static void dump_310_sprs(void)
2134{
2135#ifdef CONFIG_PPC64
2136 if (!cpu_has_feature(CPU_FTR_ARCH_31))
2137 return;
2138
2139 printf("mmcr3 = %.16lx, sier2 = %.16lx, sier3 = %.16lx\n",
2140 mfspr(SPRN_MMCR3), mfspr(SPRN_SIER2), mfspr(SPRN_SIER3));
2141
2142#endif
2143}
2144
2145static void dump_one_spr(int spr, bool show_unimplemented)
2146{
2147 unsigned long val;
2148
2149 val = 0xdeadbeef;
2150 if (!read_spr(spr, &val)) {
2151 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2152 return;
2153 }
2154
2155 if (val == 0xdeadbeef) {
2156
2157 val = 0x0badcafe;
2158 if (!read_spr(spr, &val)) {
2159 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
2160 return;
2161 }
2162
2163 if (val == 0x0badcafe) {
2164 if (show_unimplemented)
2165 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
2166 return;
2167 }
2168 }
2169
2170 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
2171}
2172
2173static void super_regs(void)
2174{
2175 static unsigned long regno;
2176 int cmd;
2177 int spr;
2178
2179 cmd = skipbl();
2180
2181 switch (cmd) {
2182 case '\n': {
2183 unsigned long sp, toc;
2184 asm("mr %0,1" : "=r" (sp) :);
2185 asm("mr %0,2" : "=r" (toc) :);
2186
2187 printf("msr = "REG" sprg0 = "REG"\n",
2188 mfmsr(), mfspr(SPRN_SPRG0));
2189 printf("pvr = "REG" sprg1 = "REG"\n",
2190 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
2191 printf("dec = "REG" sprg2 = "REG"\n",
2192 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
2193 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
2194 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
2195
2196 dump_206_sprs();
2197 dump_207_sprs();
2198 dump_300_sprs();
2199 dump_310_sprs();
2200
2201 return;
2202 }
2203 case 'w': {
2204 unsigned long val;
2205 scanhex(®no);
2206 val = 0;
2207 read_spr(regno, &val);
2208 scanhex(&val);
2209 write_spr(regno, val);
2210 dump_one_spr(regno, true);
2211 break;
2212 }
2213 case 'r':
2214 scanhex(®no);
2215 dump_one_spr(regno, true);
2216 break;
2217 case 'a':
2218
2219 for (spr = 1; spr < 1024; ++spr)
2220 dump_one_spr(spr, false);
2221 break;
2222 }
2223
2224 scannl();
2225}
2226
2227
2228
2229
2230static int
2231mread(unsigned long adrs, void *buf, int size)
2232{
2233 volatile int n;
2234 char *p, *q;
2235
2236 n = 0;
2237 if (setjmp(bus_error_jmp) == 0) {
2238 catch_memory_errors = 1;
2239 sync();
2240 p = (char *)adrs;
2241 q = (char *)buf;
2242 switch (size) {
2243 case 2:
2244 *(u16 *)q = *(u16 *)p;
2245 break;
2246 case 4:
2247 *(u32 *)q = *(u32 *)p;
2248 break;
2249 case 8:
2250 *(u64 *)q = *(u64 *)p;
2251 break;
2252 default:
2253 for( ; n < size; ++n) {
2254 *q++ = *p++;
2255 sync();
2256 }
2257 }
2258 sync();
2259
2260 __delay(200);
2261 n = size;
2262 }
2263 catch_memory_errors = 0;
2264 return n;
2265}
2266
2267static int
2268mwrite(unsigned long adrs, void *buf, int size)
2269{
2270 volatile int n;
2271 char *p, *q;
2272
2273 n = 0;
2274
2275 if (xmon_is_ro) {
2276 printf(xmon_ro_msg);
2277 return n;
2278 }
2279
2280 if (setjmp(bus_error_jmp) == 0) {
2281 catch_memory_errors = 1;
2282 sync();
2283 p = (char *) adrs;
2284 q = (char *) buf;
2285 switch (size) {
2286 case 2:
2287 *(u16 *)p = *(u16 *)q;
2288 break;
2289 case 4:
2290 *(u32 *)p = *(u32 *)q;
2291 break;
2292 case 8:
2293 *(u64 *)p = *(u64 *)q;
2294 break;
2295 default:
2296 for ( ; n < size; ++n) {
2297 *p++ = *q++;
2298 sync();
2299 }
2300 }
2301 sync();
2302
2303 __delay(200);
2304 n = size;
2305 } else {
2306 printf("*** Error writing address "REG"\n", adrs + n);
2307 }
2308 catch_memory_errors = 0;
2309 return n;
2310}
2311
2312static int
2313mread_instr(unsigned long adrs, struct ppc_inst *instr)
2314{
2315 volatile int n;
2316
2317 n = 0;
2318 if (setjmp(bus_error_jmp) == 0) {
2319 catch_memory_errors = 1;
2320 sync();
2321 *instr = ppc_inst_read((u32 *)adrs);
2322 sync();
2323
2324 __delay(200);
2325 n = ppc_inst_len(*instr);
2326 }
2327 catch_memory_errors = 0;
2328 return n;
2329}
2330
2331static int fault_type;
2332static int fault_except;
2333static char *fault_chars[] = { "--", "**", "##" };
2334
2335static int handle_fault(struct pt_regs *regs)
2336{
2337 fault_except = TRAP(regs);
2338 switch (TRAP(regs)) {
2339 case 0x200:
2340 fault_type = 0;
2341 break;
2342 case 0x300:
2343 case 0x380:
2344 fault_type = 1;
2345 break;
2346 default:
2347 fault_type = 2;
2348 }
2349
2350 longjmp(bus_error_jmp, 1);
2351
2352 return 0;
2353}
2354
2355#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2356
2357static void
2358byterev(unsigned char *val, int size)
2359{
2360 int t;
2361
2362 switch (size) {
2363 case 2:
2364 SWAP(val[0], val[1], t);
2365 break;
2366 case 4:
2367 SWAP(val[0], val[3], t);
2368 SWAP(val[1], val[2], t);
2369 break;
2370 case 8:
2371 SWAP(val[0], val[7], t);
2372 SWAP(val[1], val[6], t);
2373 SWAP(val[2], val[5], t);
2374 SWAP(val[3], val[4], t);
2375 break;
2376 }
2377}
2378
2379static int brev;
2380static int mnoread;
2381
2382static char *memex_help_string =
2383 "Memory examine command usage:\n"
2384 "m [addr] [flags] examine/change memory\n"
2385 " addr is optional. will start where left off.\n"
2386 " flags may include chars from this set:\n"
2387 " b modify by bytes (default)\n"
2388 " w modify by words (2 byte)\n"
2389 " l modify by longs (4 byte)\n"
2390 " d modify by doubleword (8 byte)\n"
2391 " r toggle reverse byte order mode\n"
2392 " n do not read memory (for i/o spaces)\n"
2393 " . ok to read (default)\n"
2394 "NOTE: flags are saved as defaults\n"
2395 "";
2396
2397static char *memex_subcmd_help_string =
2398 "Memory examine subcommands:\n"
2399 " hexval write this val to current location\n"
2400 " 'string' write chars from string to this location\n"
2401 " ' increment address\n"
2402 " ^ decrement address\n"
2403 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2404 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2405 " ` clear no-read flag\n"
2406 " ; stay at this addr\n"
2407 " v change to byte mode\n"
2408 " w change to word (2 byte) mode\n"
2409 " l change to long (4 byte) mode\n"
2410 " u change to doubleword (8 byte) mode\n"
2411 " m addr change current addr\n"
2412 " n toggle no-read flag\n"
2413 " r toggle byte reverse flag\n"
2414 " < count back up count bytes\n"
2415 " > count skip forward count bytes\n"
2416 " x exit this mode\n"
2417 "";
2418
2419static void
2420memex(void)
2421{
2422 int cmd, inc, i, nslash;
2423 unsigned long n;
2424 unsigned char val[16];
2425
2426 scanhex((void *)&adrs);
2427 cmd = skipbl();
2428 if (cmd == '?') {
2429 printf(memex_help_string);
2430 return;
2431 } else {
2432 termch = cmd;
2433 }
2434 last_cmd = "m\n";
2435 while ((cmd = skipbl()) != '\n') {
2436 switch( cmd ){
2437 case 'b': size = 1; break;
2438 case 'w': size = 2; break;
2439 case 'l': size = 4; break;
2440 case 'd': size = 8; break;
2441 case 'r': brev = !brev; break;
2442 case 'n': mnoread = 1; break;
2443 case '.': mnoread = 0; break;
2444 }
2445 }
2446 if( size <= 0 )
2447 size = 1;
2448 else if( size > 8 )
2449 size = 8;
2450 for(;;){
2451 if (!mnoread)
2452 n = mread(adrs, val, size);
2453 printf(REG"%c", adrs, brev? 'r': ' ');
2454 if (!mnoread) {
2455 if (brev)
2456 byterev(val, size);
2457 putchar(' ');
2458 for (i = 0; i < n; ++i)
2459 printf("%.2x", val[i]);
2460 for (; i < size; ++i)
2461 printf("%s", fault_chars[fault_type]);
2462 }
2463 putchar(' ');
2464 inc = size;
2465 nslash = 0;
2466 for(;;){
2467 if( scanhex(&n) ){
2468 for (i = 0; i < size; ++i)
2469 val[i] = n >> (i * 8);
2470 if (!brev)
2471 byterev(val, size);
2472 mwrite(adrs, val, size);
2473 inc = size;
2474 }
2475 cmd = skipbl();
2476 if (cmd == '\n')
2477 break;
2478 inc = 0;
2479 switch (cmd) {
2480 case '\'':
2481 for(;;){
2482 n = inchar();
2483 if( n == '\\' )
2484 n = bsesc();
2485 else if( n == '\'' )
2486 break;
2487 for (i = 0; i < size; ++i)
2488 val[i] = n >> (i * 8);
2489 if (!brev)
2490 byterev(val, size);
2491 mwrite(adrs, val, size);
2492 adrs += size;
2493 }
2494 adrs -= size;
2495 inc = size;
2496 break;
2497 case ',':
2498 adrs += size;
2499 break;
2500 case '.':
2501 mnoread = 0;
2502 break;
2503 case ';':
2504 break;
2505 case 'x':
2506 case EOF:
2507 scannl();
2508 return;
2509 case 'b':
2510 case 'v':
2511 size = 1;
2512 break;
2513 case 'w':
2514 size = 2;
2515 break;
2516 case 'l':
2517 size = 4;
2518 break;
2519 case 'u':
2520 size = 8;
2521 break;
2522 case '^':
2523 adrs -= size;
2524 break;
2525 case '/':
2526 if (nslash > 0)
2527 adrs -= 1 << nslash;
2528 else
2529 nslash = 0;
2530 nslash += 4;
2531 adrs += 1 << nslash;
2532 break;
2533 case '\\':
2534 if (nslash < 0)
2535 adrs += 1 << -nslash;
2536 else
2537 nslash = 0;
2538 nslash -= 4;
2539 adrs -= 1 << -nslash;
2540 break;
2541 case 'm':
2542 scanhex((void *)&adrs);
2543 break;
2544 case 'n':
2545 mnoread = 1;
2546 break;
2547 case 'r':
2548 brev = !brev;
2549 break;
2550 case '<':
2551 n = size;
2552 scanhex(&n);
2553 adrs -= n;
2554 break;
2555 case '>':
2556 n = size;
2557 scanhex(&n);
2558 adrs += n;
2559 break;
2560 case '?':
2561 printf(memex_subcmd_help_string);
2562 break;
2563 }
2564 }
2565 adrs += inc;
2566 }
2567}
2568
2569static int
2570bsesc(void)
2571{
2572 int c;
2573
2574 c = inchar();
2575 switch( c ){
2576 case 'n': c = '\n'; break;
2577 case 'r': c = '\r'; break;
2578 case 'b': c = '\b'; break;
2579 case 't': c = '\t'; break;
2580 }
2581 return c;
2582}
2583
2584static void xmon_rawdump (unsigned long adrs, long ndump)
2585{
2586 long n, m, r, nr;
2587 unsigned char temp[16];
2588
2589 for (n = ndump; n > 0;) {
2590 r = n < 16? n: 16;
2591 nr = mread(adrs, temp, r);
2592 adrs += nr;
2593 for (m = 0; m < r; ++m) {
2594 if (m < nr)
2595 printf("%.2x", temp[m]);
2596 else
2597 printf("%s", fault_chars[fault_type]);
2598 }
2599 n -= r;
2600 if (nr < r)
2601 break;
2602 }
2603 printf("\n");
2604}
2605
2606static void dump_tracing(void)
2607{
2608 int c;
2609
2610 c = inchar();
2611 if (c == 'c')
2612 ftrace_dump(DUMP_ORIG);
2613 else
2614 ftrace_dump(DUMP_ALL);
2615}
2616
2617#ifdef CONFIG_PPC64
2618static void dump_one_paca(int cpu)
2619{
2620 struct paca_struct *p;
2621#ifdef CONFIG_PPC_BOOK3S_64
2622 int i = 0;
2623#endif
2624
2625 if (setjmp(bus_error_jmp) != 0) {
2626 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2627 return;
2628 }
2629
2630 catch_memory_errors = 1;
2631 sync();
2632
2633 p = paca_ptrs[cpu];
2634
2635 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
2636
2637 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2638 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2639 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
2640
2641#define DUMP(paca, name, format) \
2642 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
2643 offsetof(struct paca_struct, name));
2644
2645 DUMP(p, lock_token, "%#-*x");
2646 DUMP(p, paca_index, "%#-*x");
2647 DUMP(p, kernel_toc, "%#-*llx");
2648 DUMP(p, kernelbase, "%#-*llx");
2649 DUMP(p, kernel_msr, "%#-*llx");
2650 DUMP(p, emergency_sp, "%-*px");
2651#ifdef CONFIG_PPC_BOOK3S_64
2652 DUMP(p, nmi_emergency_sp, "%-*px");
2653 DUMP(p, mc_emergency_sp, "%-*px");
2654 DUMP(p, in_nmi, "%#-*x");
2655 DUMP(p, in_mce, "%#-*x");
2656 DUMP(p, hmi_event_available, "%#-*x");
2657#endif
2658 DUMP(p, data_offset, "%#-*llx");
2659 DUMP(p, hw_cpu_id, "%#-*x");
2660 DUMP(p, cpu_start, "%#-*x");
2661 DUMP(p, kexec_state, "%#-*x");
2662#ifdef CONFIG_PPC_BOOK3S_64
2663 if (!early_radix_enabled()) {
2664 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2665 u64 esid, vsid;
2666
2667 if (!p->slb_shadow_ptr)
2668 continue;
2669
2670 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2671 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2672
2673 if (esid || vsid) {
2674 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2675 22, "slb_shadow", i, esid, vsid);
2676 }
2677 }
2678 DUMP(p, vmalloc_sllp, "%#-*x");
2679 DUMP(p, stab_rr, "%#-*x");
2680 DUMP(p, slb_used_bitmap, "%#-*x");
2681 DUMP(p, slb_kern_bitmap, "%#-*x");
2682
2683 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2684 DUMP(p, slb_cache_ptr, "%#-*x");
2685 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
2686 printf(" %-*s[%d] = 0x%016x\n",
2687 22, "slb_cache", i, p->slb_cache[i]);
2688 }
2689 }
2690
2691 DUMP(p, rfi_flush_fallback_area, "%-*px");
2692#endif
2693 DUMP(p, dscr_default, "%#-*llx");
2694#ifdef CONFIG_PPC_BOOK3E
2695 DUMP(p, pgd, "%-*px");
2696 DUMP(p, kernel_pgd, "%-*px");
2697 DUMP(p, tcd_ptr, "%-*px");
2698 DUMP(p, mc_kstack, "%-*px");
2699 DUMP(p, crit_kstack, "%-*px");
2700 DUMP(p, dbg_kstack, "%-*px");
2701#endif
2702 DUMP(p, __current, "%-*px");
2703 DUMP(p, kstack, "%#-*llx");
2704 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
2705#ifdef CONFIG_STACKPROTECTOR
2706 DUMP(p, canary, "%#-*lx");
2707#endif
2708 DUMP(p, saved_r1, "%#-*llx");
2709#ifdef CONFIG_PPC_BOOK3E
2710 DUMP(p, trap_save, "%#-*x");
2711#endif
2712 DUMP(p, irq_soft_mask, "%#-*x");
2713 DUMP(p, irq_happened, "%#-*x");
2714#ifdef CONFIG_MMIOWB
2715 DUMP(p, mmiowb_state.nesting_count, "%#-*x");
2716 DUMP(p, mmiowb_state.mmiowb_pending, "%#-*x");
2717#endif
2718 DUMP(p, irq_work_pending, "%#-*x");
2719 DUMP(p, sprg_vdso, "%#-*llx");
2720
2721#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
2722 DUMP(p, tm_scratch, "%#-*llx");
2723#endif
2724
2725#ifdef CONFIG_PPC_POWERNV
2726 DUMP(p, idle_state, "%#-*lx");
2727 if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
2728 DUMP(p, thread_idle_state, "%#-*x");
2729 DUMP(p, subcore_sibling_mask, "%#-*x");
2730 } else {
2731#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
2732 DUMP(p, requested_psscr, "%#-*llx");
2733 DUMP(p, dont_stop.counter, "%#-*x");
2734#endif
2735 }
2736#endif
2737
2738 DUMP(p, accounting.utime, "%#-*lx");
2739 DUMP(p, accounting.stime, "%#-*lx");
2740#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2741 DUMP(p, accounting.utime_scaled, "%#-*lx");
2742#endif
2743 DUMP(p, accounting.starttime, "%#-*lx");
2744 DUMP(p, accounting.starttime_user, "%#-*lx");
2745#ifdef CONFIG_ARCH_HAS_SCALED_CPUTIME
2746 DUMP(p, accounting.startspurr, "%#-*lx");
2747 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2748#endif
2749 DUMP(p, accounting.steal_time, "%#-*lx");
2750#undef DUMP
2751
2752 catch_memory_errors = 0;
2753 sync();
2754}
2755
2756static void dump_all_pacas(void)
2757{
2758 int cpu;
2759
2760 if (num_possible_cpus() == 0) {
2761 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2762 return;
2763 }
2764
2765 for_each_possible_cpu(cpu)
2766 dump_one_paca(cpu);
2767}
2768
2769static void dump_pacas(void)
2770{
2771 unsigned long num;
2772 int c;
2773
2774 c = inchar();
2775 if (c == 'a') {
2776 dump_all_pacas();
2777 return;
2778 }
2779
2780 termch = c;
2781
2782 if (scanhex(&num))
2783 dump_one_paca(num);
2784 else
2785 dump_one_paca(xmon_owner);
2786}
2787#endif
2788
2789#ifdef CONFIG_PPC_POWERNV
2790static void dump_one_xive(int cpu)
2791{
2792 unsigned int hwid = get_hard_smp_processor_id(cpu);
2793 bool hv = cpu_has_feature(CPU_FTR_HVMODE);
2794
2795 if (hv) {
2796 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2797 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2798 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2799 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2800 opal_xive_dump(XIVE_DUMP_VP, hwid);
2801 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2802 }
2803
2804 if (setjmp(bus_error_jmp) != 0) {
2805 catch_memory_errors = 0;
2806 printf("*** Error dumping xive on cpu %d\n", cpu);
2807 return;
2808 }
2809
2810 catch_memory_errors = 1;
2811 sync();
2812 xmon_xive_do_dump(cpu);
2813 sync();
2814 __delay(200);
2815 catch_memory_errors = 0;
2816}
2817
2818static void dump_all_xives(void)
2819{
2820 int cpu;
2821
2822 if (num_possible_cpus() == 0) {
2823 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2824 return;
2825 }
2826
2827 for_each_possible_cpu(cpu)
2828 dump_one_xive(cpu);
2829}
2830
2831static void dump_xives(void)
2832{
2833 unsigned long num;
2834 int c;
2835
2836 if (!xive_enabled()) {
2837 printf("Xive disabled on this system\n");
2838 return;
2839 }
2840
2841 c = inchar();
2842 if (c == 'a') {
2843 dump_all_xives();
2844 return;
2845 } else if (c == 'i') {
2846 if (scanhex(&num))
2847 xmon_xive_get_irq_config(num, NULL);
2848 else
2849 xmon_xive_get_irq_all();
2850 return;
2851 }
2852
2853 termch = c;
2854
2855 if (scanhex(&num))
2856 dump_one_xive(num);
2857 else
2858 dump_one_xive(xmon_owner);
2859}
2860#endif
2861
2862static void dump_by_size(unsigned long addr, long count, int size)
2863{
2864 unsigned char temp[16];
2865 int i, j;
2866 u64 val;
2867
2868 count = ALIGN(count, 16);
2869
2870 for (i = 0; i < count; i += 16, addr += 16) {
2871 printf(REG, addr);
2872
2873 if (mread(addr, temp, 16) != 16) {
2874 printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2875 return;
2876 }
2877
2878 for (j = 0; j < 16; j += size) {
2879 putchar(' ');
2880 switch (size) {
2881 case 1: val = temp[j]; break;
2882 case 2: val = *(u16 *)&temp[j]; break;
2883 case 4: val = *(u32 *)&temp[j]; break;
2884 case 8: val = *(u64 *)&temp[j]; break;
2885 default: val = 0;
2886 }
2887
2888 printf("%0*llx", size * 2, val);
2889 }
2890 printf(" |");
2891 for (j = 0; j < 16; ++j) {
2892 val = temp[j];
2893 putchar(' ' <= val && val <= '~' ? val : '.');
2894 }
2895 printf("|\n");
2896 }
2897}
2898
2899static void
2900dump(void)
2901{
2902 static char last[] = { "d?\n" };
2903 int c;
2904
2905 c = inchar();
2906
2907#ifdef CONFIG_PPC64
2908 if (c == 'p') {
2909 xmon_start_pagination();
2910 dump_pacas();
2911 xmon_end_pagination();
2912 return;
2913 }
2914#endif
2915#ifdef CONFIG_PPC_POWERNV
2916 if (c == 'x') {
2917 xmon_start_pagination();
2918 dump_xives();
2919 xmon_end_pagination();
2920 return;
2921 }
2922#endif
2923
2924 if (c == 't') {
2925 dump_tracing();
2926 return;
2927 }
2928
2929 if (c == '\n')
2930 termch = c;
2931
2932 scanhex((void *)&adrs);
2933 if (termch != '\n')
2934 termch = 0;
2935 if (c == 'i') {
2936 scanhex(&nidump);
2937 if (nidump == 0)
2938 nidump = 16;
2939 else if (nidump > MAX_IDUMP)
2940 nidump = MAX_IDUMP;
2941 adrs += ppc_inst_dump(adrs, nidump, 1);
2942 last_cmd = "di\n";
2943 } else if (c == 'l') {
2944 dump_log_buf();
2945 } else if (c == 'o') {
2946 dump_opal_msglog();
2947 } else if (c == 'v') {
2948
2949 show_pte(adrs);
2950 } else if (c == 'r') {
2951 scanhex(&ndump);
2952 if (ndump == 0)
2953 ndump = 64;
2954 xmon_rawdump(adrs, ndump);
2955 adrs += ndump;
2956 last_cmd = "dr\n";
2957 } else {
2958 scanhex(&ndump);
2959 if (ndump == 0)
2960 ndump = 64;
2961 else if (ndump > MAX_DUMP)
2962 ndump = MAX_DUMP;
2963
2964 switch (c) {
2965 case '8':
2966 case '4':
2967 case '2':
2968 case '1':
2969 ndump = ALIGN(ndump, 16);
2970 dump_by_size(adrs, ndump, c - '0');
2971 last[1] = c;
2972 last_cmd = last;
2973 break;
2974 default:
2975 prdump(adrs, ndump);
2976 last_cmd = "d\n";
2977 }
2978
2979 adrs += ndump;
2980 }
2981}
2982
2983static void
2984prdump(unsigned long adrs, long ndump)
2985{
2986 long n, m, c, r, nr;
2987 unsigned char temp[16];
2988
2989 for (n = ndump; n > 0;) {
2990 printf(REG, adrs);
2991 putchar(' ');
2992 r = n < 16? n: 16;
2993 nr = mread(adrs, temp, r);
2994 adrs += nr;
2995 for (m = 0; m < r; ++m) {
2996 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2997 putchar(' ');
2998 if (m < nr)
2999 printf("%.2x", temp[m]);
3000 else
3001 printf("%s", fault_chars[fault_type]);
3002 }
3003 for (; m < 16; ++m) {
3004 if ((m & (sizeof(long) - 1)) == 0)
3005 putchar(' ');
3006 printf(" ");
3007 }
3008 printf(" |");
3009 for (m = 0; m < r; ++m) {
3010 if (m < nr) {
3011 c = temp[m];
3012 putchar(' ' <= c && c <= '~'? c: '.');
3013 } else
3014 putchar(' ');
3015 }
3016 n -= r;
3017 for (; m < 16; ++m)
3018 putchar(' ');
3019 printf("|\n");
3020 if (nr < r)
3021 break;
3022 }
3023}
3024
3025typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
3026
3027static int
3028generic_inst_dump(unsigned long adr, long count, int praddr,
3029 instruction_dump_func dump_func)
3030{
3031 int nr, dotted;
3032 unsigned long first_adr;
3033 struct ppc_inst inst, last_inst = ppc_inst(0);
3034
3035 dotted = 0;
3036 for (first_adr = adr; count > 0; --count, adr += ppc_inst_len(inst)) {
3037 nr = mread_instr(adr, &inst);
3038 if (nr == 0) {
3039 if (praddr) {
3040 const char *x = fault_chars[fault_type];
3041 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
3042 }
3043 break;
3044 }
3045 if (adr > first_adr && ppc_inst_equal(inst, last_inst)) {
3046 if (!dotted) {
3047 printf(" ...\n");
3048 dotted = 1;
3049 }
3050 continue;
3051 }
3052 dotted = 0;
3053 last_inst = inst;
3054 if (praddr)
3055 printf(REG" %s", adr, ppc_inst_as_str(inst));
3056 printf("\t");
3057 if (!ppc_inst_prefixed(inst))
3058 dump_func(ppc_inst_val(inst), adr);
3059 else
3060 dump_func(ppc_inst_as_ulong(inst), adr);
3061 printf("\n");
3062 }
3063 return adr - first_adr;
3064}
3065
3066static int
3067ppc_inst_dump(unsigned long adr, long count, int praddr)
3068{
3069 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
3070}
3071
3072void
3073print_address(unsigned long addr)
3074{
3075 xmon_print_symbol(addr, "\t# ", "");
3076}
3077
3078static void
3079dump_log_buf(void)
3080{
3081 struct kmsg_dump_iter iter;
3082 static unsigned char buf[1024];
3083 size_t len;
3084
3085 if (setjmp(bus_error_jmp) != 0) {
3086 printf("Error dumping printk buffer!\n");
3087 return;
3088 }
3089
3090 catch_memory_errors = 1;
3091 sync();
3092
3093 kmsg_dump_rewind(&iter);
3094 xmon_start_pagination();
3095 while (kmsg_dump_get_line(&iter, false, buf, sizeof(buf), &len)) {
3096 buf[len] = '\0';
3097 printf("%s", buf);
3098 }
3099 xmon_end_pagination();
3100
3101 sync();
3102
3103 __delay(200);
3104 catch_memory_errors = 0;
3105}
3106
3107#ifdef CONFIG_PPC_POWERNV
3108static void dump_opal_msglog(void)
3109{
3110 unsigned char buf[128];
3111 ssize_t res;
3112 volatile loff_t pos = 0;
3113
3114 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
3115 printf("Machine is not running OPAL firmware.\n");
3116 return;
3117 }
3118
3119 if (setjmp(bus_error_jmp) != 0) {
3120 printf("Error dumping OPAL msglog!\n");
3121 return;
3122 }
3123
3124 catch_memory_errors = 1;
3125 sync();
3126
3127 xmon_start_pagination();
3128 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
3129 if (res < 0) {
3130 printf("Error dumping OPAL msglog! Error: %zd\n", res);
3131 break;
3132 }
3133 buf[res] = '\0';
3134 printf("%s", buf);
3135 pos += res;
3136 }
3137 xmon_end_pagination();
3138
3139 sync();
3140
3141 __delay(200);
3142 catch_memory_errors = 0;
3143}
3144#endif
3145
3146
3147
3148
3149static unsigned long mdest;
3150static unsigned long msrc;
3151static unsigned long mval;
3152static unsigned long mcount;
3153static unsigned long mdiffs;
3154
3155static void
3156memops(int cmd)
3157{
3158 scanhex((void *)&mdest);
3159 if( termch != '\n' )
3160 termch = 0;
3161 scanhex((void *)(cmd == 's'? &mval: &msrc));
3162 if( termch != '\n' )
3163 termch = 0;
3164 scanhex((void *)&mcount);
3165 switch( cmd ){
3166 case 'm':
3167 if (xmon_is_ro) {
3168 printf(xmon_ro_msg);
3169 break;
3170 }
3171 memmove((void *)mdest, (void *)msrc, mcount);
3172 break;
3173 case 's':
3174 if (xmon_is_ro) {
3175 printf(xmon_ro_msg);
3176 break;
3177 }
3178 memset((void *)mdest, mval, mcount);
3179 break;
3180 case 'd':
3181 if( termch != '\n' )
3182 termch = 0;
3183 scanhex((void *)&mdiffs);
3184 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
3185 break;
3186 }
3187}
3188
3189static void
3190memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
3191{
3192 unsigned n, prt;
3193
3194 prt = 0;
3195 for( n = nb; n > 0; --n )
3196 if( *p1++ != *p2++ )
3197 if( ++prt <= maxpr )
3198 printf("%px %.2x # %px %.2x\n", p1 - 1,
3199 p1[-1], p2 - 1, p2[-1]);
3200 if( prt > maxpr )
3201 printf("Total of %d differences\n", prt);
3202}
3203
3204static unsigned mend;
3205static unsigned mask;
3206
3207static void
3208memlocate(void)
3209{
3210 unsigned a, n;
3211 unsigned char val[4];
3212
3213 last_cmd = "ml";
3214 scanhex((void *)&mdest);
3215 if (termch != '\n') {
3216 termch = 0;
3217 scanhex((void *)&mend);
3218 if (termch != '\n') {
3219 termch = 0;
3220 scanhex((void *)&mval);
3221 mask = ~0;
3222 if (termch != '\n') termch = 0;
3223 scanhex((void *)&mask);
3224 }
3225 }
3226 n = 0;
3227 for (a = mdest; a < mend; a += 4) {
3228 if (mread(a, val, 4) == 4
3229 && ((GETWORD(val) ^ mval) & mask) == 0) {
3230 printf("%.16x: %.16x\n", a, GETWORD(val));
3231 if (++n >= 10)
3232 break;
3233 }
3234 }
3235}
3236
3237static unsigned long mskip = 0x1000;
3238static unsigned long mlim = 0xffffffff;
3239
3240static void
3241memzcan(void)
3242{
3243 unsigned char v;
3244 unsigned a;
3245 int ok, ook;
3246
3247 scanhex(&mdest);
3248 if (termch != '\n') termch = 0;
3249 scanhex(&mskip);
3250 if (termch != '\n') termch = 0;
3251 scanhex(&mlim);
3252 ook = 0;
3253 for (a = mdest; a < mlim; a += mskip) {
3254 ok = mread(a, &v, 1);
3255 if (ok && !ook) {
3256 printf("%.8x .. ", a);
3257 } else if (!ok && ook)
3258 printf("%.8lx\n", a - mskip);
3259 ook = ok;
3260 if (a + mskip < a)
3261 break;
3262 }
3263 if (ook)
3264 printf("%.8lx\n", a - mskip);
3265}
3266
3267static void show_task(struct task_struct *volatile tsk)
3268{
3269 unsigned int p_state = READ_ONCE(tsk->__state);
3270 char state;
3271
3272
3273
3274
3275
3276
3277 state = (p_state == 0) ? 'R' :
3278 (p_state < 0) ? 'U' :
3279 (p_state & TASK_UNINTERRUPTIBLE) ? 'D' :
3280 (p_state & TASK_STOPPED) ? 'T' :
3281 (p_state & TASK_TRACED) ? 'C' :
3282 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
3283 (tsk->exit_state & EXIT_DEAD) ? 'E' :
3284 (p_state & TASK_INTERRUPTIBLE) ? 'S' : '?';
3285
3286 printf("%16px %16lx %16px %6d %6d %c %2d %s\n", tsk,
3287 tsk->thread.ksp, tsk->thread.regs,
3288 tsk->pid, rcu_dereference(tsk->parent)->pid,
3289 state, task_cpu(tsk),
3290 tsk->comm);
3291}
3292
3293#ifdef CONFIG_PPC_BOOK3S_64
3294static void format_pte(void *ptep, unsigned long pte)
3295{
3296 pte_t entry = __pte(pte);
3297
3298 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
3299 printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
3300
3301 printf("Flags = %s%s%s%s%s\n",
3302 pte_young(entry) ? "Accessed " : "",
3303 pte_dirty(entry) ? "Dirty " : "",
3304 pte_read(entry) ? "Read " : "",
3305 pte_write(entry) ? "Write " : "",
3306 pte_exec(entry) ? "Exec " : "");
3307}
3308
3309static void show_pte(unsigned long addr)
3310{
3311 unsigned long tskv = 0;
3312 struct task_struct *volatile tsk = NULL;
3313 struct mm_struct *mm;
3314 pgd_t *pgdp;
3315 p4d_t *p4dp;
3316 pud_t *pudp;
3317 pmd_t *pmdp;
3318 pte_t *ptep;
3319
3320 if (!scanhex(&tskv))
3321 mm = &init_mm;
3322 else
3323 tsk = (struct task_struct *)tskv;
3324
3325 if (tsk == NULL)
3326 mm = &init_mm;
3327 else
3328 mm = tsk->active_mm;
3329
3330 if (setjmp(bus_error_jmp) != 0) {
3331 catch_memory_errors = 0;
3332 printf("*** Error dumping pte for task %px\n", tsk);
3333 return;
3334 }
3335
3336 catch_memory_errors = 1;
3337 sync();
3338
3339 if (mm == &init_mm)
3340 pgdp = pgd_offset_k(addr);
3341 else
3342 pgdp = pgd_offset(mm, addr);
3343
3344 p4dp = p4d_offset(pgdp, addr);
3345
3346 if (p4d_none(*p4dp)) {
3347 printf("No valid P4D\n");
3348 return;
3349 }
3350
3351 if (p4d_is_leaf(*p4dp)) {
3352 format_pte(p4dp, p4d_val(*p4dp));
3353 return;
3354 }
3355
3356 printf("p4dp @ 0x%px = 0x%016lx\n", p4dp, p4d_val(*p4dp));
3357
3358 pudp = pud_offset(p4dp, addr);
3359
3360 if (pud_none(*pudp)) {
3361 printf("No valid PUD\n");
3362 return;
3363 }
3364
3365 if (pud_is_leaf(*pudp)) {
3366 format_pte(pudp, pud_val(*pudp));
3367 return;
3368 }
3369
3370 printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
3371
3372 pmdp = pmd_offset(pudp, addr);
3373
3374 if (pmd_none(*pmdp)) {
3375 printf("No valid PMD\n");
3376 return;
3377 }
3378
3379 if (pmd_is_leaf(*pmdp)) {
3380 format_pte(pmdp, pmd_val(*pmdp));
3381 return;
3382 }
3383 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
3384
3385 ptep = pte_offset_map(pmdp, addr);
3386 if (pte_none(*ptep)) {
3387 printf("no valid PTE\n");
3388 return;
3389 }
3390
3391 format_pte(ptep, pte_val(*ptep));
3392
3393 sync();
3394 __delay(200);
3395 catch_memory_errors = 0;
3396}
3397#else
3398static void show_pte(unsigned long addr)
3399{
3400 printf("show_pte not yet implemented\n");
3401}
3402#endif
3403
3404static void show_tasks(void)
3405{
3406 unsigned long tskv;
3407 struct task_struct *volatile tsk = NULL;
3408
3409 printf(" task_struct ->thread.ksp ->thread.regs PID PPID S P CMD\n");
3410
3411 if (scanhex(&tskv))
3412 tsk = (struct task_struct *)tskv;
3413
3414 if (setjmp(bus_error_jmp) != 0) {
3415 catch_memory_errors = 0;
3416 printf("*** Error dumping task %px\n", tsk);
3417 return;
3418 }
3419
3420 catch_memory_errors = 1;
3421 sync();
3422
3423 if (tsk)
3424 show_task(tsk);
3425 else
3426 for_each_process(tsk)
3427 show_task(tsk);
3428
3429 sync();
3430 __delay(200);
3431 catch_memory_errors = 0;
3432}
3433
3434static void proccall(void)
3435{
3436 unsigned long args[8];
3437 unsigned long ret;
3438 int i;
3439 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3440 unsigned long, unsigned long, unsigned long,
3441 unsigned long, unsigned long, unsigned long);
3442 callfunc_t func;
3443
3444 if (!scanhex(&adrs))
3445 return;
3446 if (termch != '\n')
3447 termch = 0;
3448 for (i = 0; i < 8; ++i)
3449 args[i] = 0;
3450 for (i = 0; i < 8; ++i) {
3451 if (!scanhex(&args[i]) || termch == '\n')
3452 break;
3453 termch = 0;
3454 }
3455 func = (callfunc_t) adrs;
3456 ret = 0;
3457 if (setjmp(bus_error_jmp) == 0) {
3458 catch_memory_errors = 1;
3459 sync();
3460 ret = func(args[0], args[1], args[2], args[3],
3461 args[4], args[5], args[6], args[7]);
3462 sync();
3463 printf("return value is 0x%lx\n", ret);
3464 } else {
3465 printf("*** %x exception occurred\n", fault_except);
3466 }
3467 catch_memory_errors = 0;
3468}
3469
3470
3471int
3472skipbl(void)
3473{
3474 int c;
3475
3476 if( termch != 0 ){
3477 c = termch;
3478 termch = 0;
3479 } else
3480 c = inchar();
3481 while( c == ' ' || c == '\t' )
3482 c = inchar();
3483 return c;
3484}
3485
3486#define N_PTREGS 44
3487static const char *regnames[N_PTREGS] = {
3488 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3489 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3490 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3491 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
3492 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3493#ifdef CONFIG_PPC64
3494 "softe",
3495#else
3496 "mq",
3497#endif
3498 "trap", "dar", "dsisr", "res"
3499};
3500
3501int
3502scanhex(unsigned long *vp)
3503{
3504 int c, d;
3505 unsigned long v;
3506
3507 c = skipbl();
3508 if (c == '%') {
3509
3510 char regname[8];
3511 int i;
3512
3513 for (i = 0; i < sizeof(regname) - 1; ++i) {
3514 c = inchar();
3515 if (!isalnum(c)) {
3516 termch = c;
3517 break;
3518 }
3519 regname[i] = c;
3520 }
3521 regname[i] = 0;
3522 i = match_string(regnames, N_PTREGS, regname);
3523 if (i < 0) {
3524 printf("invalid register name '%%%s'\n", regname);
3525 return 0;
3526 }
3527 if (xmon_regs == NULL) {
3528 printf("regs not available\n");
3529 return 0;
3530 }
3531 *vp = ((unsigned long *)xmon_regs)[i];
3532 return 1;
3533 }
3534
3535
3536
3537 if (c == '0') {
3538 c = inchar();
3539 if (c == 'x') {
3540 c = inchar();
3541 } else {
3542 d = hexdigit(c);
3543 if (d == EOF) {
3544 termch = c;
3545 *vp = 0;
3546 return 1;
3547 }
3548 }
3549 } else if (c == '$') {
3550 int i;
3551 for (i=0; i<63; i++) {
3552 c = inchar();
3553 if (isspace(c) || c == '\0') {
3554 termch = c;
3555 break;
3556 }
3557 tmpstr[i] = c;
3558 }
3559 tmpstr[i++] = 0;
3560 *vp = 0;
3561 if (setjmp(bus_error_jmp) == 0) {
3562 catch_memory_errors = 1;
3563 sync();
3564 *vp = kallsyms_lookup_name(tmpstr);
3565 sync();
3566 }
3567 catch_memory_errors = 0;
3568 if (!(*vp)) {
3569 printf("unknown symbol '%s'\n", tmpstr);
3570 return 0;
3571 }
3572 return 1;
3573 }
3574
3575 d = hexdigit(c);
3576 if (d == EOF) {
3577 termch = c;
3578 return 0;
3579 }
3580 v = 0;
3581 do {
3582 v = (v << 4) + d;
3583 c = inchar();
3584 d = hexdigit(c);
3585 } while (d != EOF);
3586 termch = c;
3587 *vp = v;
3588 return 1;
3589}
3590
3591static void
3592scannl(void)
3593{
3594 int c;
3595
3596 c = termch;
3597 termch = 0;
3598 while( c != '\n' )
3599 c = inchar();
3600}
3601
3602static int hexdigit(int c)
3603{
3604 if( '0' <= c && c <= '9' )
3605 return c - '0';
3606 if( 'A' <= c && c <= 'F' )
3607 return c - ('A' - 10);
3608 if( 'a' <= c && c <= 'f' )
3609 return c - ('a' - 10);
3610 return EOF;
3611}
3612
3613void
3614getstring(char *s, int size)
3615{
3616 int c;
3617
3618 c = skipbl();
3619 if (c == '\n') {
3620 *s = 0;
3621 return;
3622 }
3623
3624 do {
3625 if( size > 1 ){
3626 *s++ = c;
3627 --size;
3628 }
3629 c = inchar();
3630 } while( c != ' ' && c != '\t' && c != '\n' );
3631 termch = c;
3632 *s = 0;
3633}
3634
3635static char line[256];
3636static char *lineptr;
3637
3638static void
3639flush_input(void)
3640{
3641 lineptr = NULL;
3642}
3643
3644static int
3645inchar(void)
3646{
3647 if (lineptr == NULL || *lineptr == 0) {
3648 if (xmon_gets(line, sizeof(line)) == NULL) {
3649 lineptr = NULL;
3650 return EOF;
3651 }
3652 lineptr = line;
3653 }
3654 return *lineptr++;
3655}
3656
3657static void
3658take_input(char *str)
3659{
3660 lineptr = str;
3661}
3662
3663
3664static void
3665symbol_lookup(void)
3666{
3667 int type = inchar();
3668 unsigned long addr, cpu;
3669 void __percpu *ptr = NULL;
3670 static char tmp[64];
3671
3672 switch (type) {
3673 case 'a':
3674 if (scanhex(&addr))
3675 xmon_print_symbol(addr, ": ", "\n");
3676 termch = 0;
3677 break;
3678 case 's':
3679 getstring(tmp, 64);
3680 if (setjmp(bus_error_jmp) == 0) {
3681 catch_memory_errors = 1;
3682 sync();
3683 addr = kallsyms_lookup_name(tmp);
3684 if (addr)
3685 printf("%s: %lx\n", tmp, addr);
3686 else
3687 printf("Symbol '%s' not found.\n", tmp);
3688 sync();
3689 }
3690 catch_memory_errors = 0;
3691 termch = 0;
3692 break;
3693 case 'p':
3694 getstring(tmp, 64);
3695 if (setjmp(bus_error_jmp) == 0) {
3696 catch_memory_errors = 1;
3697 sync();
3698 ptr = (void __percpu *)kallsyms_lookup_name(tmp);
3699 sync();
3700 }
3701
3702 if (ptr &&
3703 ptr >= (void __percpu *)__per_cpu_start &&
3704 ptr < (void __percpu *)__per_cpu_end)
3705 {
3706 if (scanhex(&cpu) && cpu < num_possible_cpus()) {
3707 addr = (unsigned long)per_cpu_ptr(ptr, cpu);
3708 } else {
3709 cpu = raw_smp_processor_id();
3710 addr = (unsigned long)this_cpu_ptr(ptr);
3711 }
3712
3713 printf("%s for cpu 0x%lx: %lx\n", tmp, cpu, addr);
3714 } else {
3715 printf("Percpu symbol '%s' not found.\n", tmp);
3716 }
3717
3718 catch_memory_errors = 0;
3719 termch = 0;
3720 break;
3721 }
3722}
3723
3724
3725
3726static void xmon_print_symbol(unsigned long address, const char *mid,
3727 const char *after)
3728{
3729 char *modname;
3730 const char *volatile name = NULL;
3731 unsigned long offset, size;
3732
3733 printf(REG, address);
3734 if (setjmp(bus_error_jmp) == 0) {
3735 catch_memory_errors = 1;
3736 sync();
3737 name = kallsyms_lookup(address, &size, &offset, &modname,
3738 tmpstr);
3739 sync();
3740
3741 __delay(200);
3742 }
3743
3744 catch_memory_errors = 0;
3745
3746 if (name) {
3747 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3748 if (modname)
3749 printf(" [%s]", modname);
3750 }
3751 printf("%s", after);
3752}
3753
3754#ifdef CONFIG_PPC_BOOK3S_64
3755void dump_segments(void)
3756{
3757 int i;
3758 unsigned long esid,vsid;
3759 unsigned long llp;
3760
3761 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
3762
3763 for (i = 0; i < mmu_slb_size; i++) {
3764 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3765 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
3766
3767 if (!esid && !vsid)
3768 continue;
3769
3770 printf("%02d %016lx %016lx", i, esid, vsid);
3771
3772 if (!(esid & SLB_ESID_V)) {
3773 printf("\n");
3774 continue;
3775 }
3776
3777 llp = vsid & SLB_VSID_LLP;
3778 if (vsid & SLB_VSID_B_1T) {
3779 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3780 GET_ESID_1T(esid),
3781 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3782 llp);
3783 } else {
3784 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3785 GET_ESID(esid),
3786 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3787 llp);
3788 }
3789 }
3790}
3791#endif
3792
3793#ifdef CONFIG_PPC_BOOK3S_32
3794void dump_segments(void)
3795{
3796 int i;
3797
3798 printf("sr0-15 =");
3799 for (i = 0; i < 16; ++i)
3800 printf(" %x", mfsr(i << 28));
3801 printf("\n");
3802}
3803#endif
3804
3805#ifdef CONFIG_44x
3806static void dump_tlb_44x(void)
3807{
3808 int i;
3809
3810 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3811 unsigned long w0,w1,w2;
3812 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3813 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3814 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
3815 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
3816 if (w0 & PPC44x_TLB_VALID) {
3817 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
3818 w0 & PPC44x_TLB_EPN_MASK,
3819 w1 & PPC44x_TLB_ERPN_MASK,
3820 w1 & PPC44x_TLB_RPN_MASK,
3821 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3822 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3823 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3824 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3825 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3826 }
3827 printf("\n");
3828 }
3829}
3830#endif
3831
3832#ifdef CONFIG_PPC_BOOK3E
3833static void dump_tlb_book3e(void)
3834{
3835 u32 mmucfg, pidmask, lpidmask;
3836 u64 ramask;
3837 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3838 int mmu_version;
3839 static const char *pgsz_names[] = {
3840 " 1K",
3841 " 2K",
3842 " 4K",
3843 " 8K",
3844 " 16K",
3845 " 32K",
3846 " 64K",
3847 "128K",
3848 "256K",
3849 "512K",
3850 " 1M",
3851 " 2M",
3852 " 4M",
3853 " 8M",
3854 " 16M",
3855 " 32M",
3856 " 64M",
3857 "128M",
3858 "256M",
3859 "512M",
3860 " 1G",
3861 " 2G",
3862 " 4G",
3863 " 8G",
3864 " 16G",
3865 " 32G",
3866 " 64G",
3867 "128G",
3868 "256G",
3869 "512G",
3870 " 1T",
3871 " 2T",
3872 };
3873
3874
3875 mmucfg = mfspr(SPRN_MMUCFG);
3876 mmu_version = (mmucfg & 3) + 1;
3877 ntlbs = ((mmucfg >> 2) & 3) + 1;
3878 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3879 lpidsz = (mmucfg >> 24) & 0xf;
3880 rasz = (mmucfg >> 16) & 0x7f;
3881 if ((mmu_version > 1) && (mmucfg & 0x10000))
3882 lrat = 1;
3883 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3884 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3885 pidmask = (1ul << pidsz) - 1;
3886 lpidmask = (1ul << lpidsz) - 1;
3887 ramask = (1ull << rasz) - 1;
3888
3889 for (tlb = 0; tlb < ntlbs; tlb++) {
3890 u32 tlbcfg;
3891 int nent, assoc, new_cc = 1;
3892 printf("TLB %d:\n------\n", tlb);
3893 switch(tlb) {
3894 case 0:
3895 tlbcfg = mfspr(SPRN_TLB0CFG);
3896 break;
3897 case 1:
3898 tlbcfg = mfspr(SPRN_TLB1CFG);
3899 break;
3900 case 2:
3901 tlbcfg = mfspr(SPRN_TLB2CFG);
3902 break;
3903 case 3:
3904 tlbcfg = mfspr(SPRN_TLB3CFG);
3905 break;
3906 default:
3907 printf("Unsupported TLB number !\n");
3908 continue;
3909 }
3910 nent = tlbcfg & 0xfff;
3911 assoc = (tlbcfg >> 24) & 0xff;
3912 for (i = 0; i < nent; i++) {
3913 u32 mas0 = MAS0_TLBSEL(tlb);
3914 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3915 u64 mas2 = 0;
3916 u64 mas7_mas3;
3917 int esel = i, cc = i;
3918
3919 if (assoc != 0) {
3920 cc = i / assoc;
3921 esel = i % assoc;
3922 mas2 = cc * 0x1000;
3923 }
3924
3925 mas0 |= MAS0_ESEL(esel);
3926 mtspr(SPRN_MAS0, mas0);
3927 mtspr(SPRN_MAS1, mas1);
3928 mtspr(SPRN_MAS2, mas2);
3929 asm volatile("tlbre 0,0,0" : : : "memory");
3930 mas1 = mfspr(SPRN_MAS1);
3931 mas2 = mfspr(SPRN_MAS2);
3932 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3933 if (assoc && (i % assoc) == 0)
3934 new_cc = 1;
3935 if (!(mas1 & MAS1_VALID))
3936 continue;
3937 if (assoc == 0)
3938 printf("%04x- ", i);
3939 else if (new_cc)
3940 printf("%04x-%c", cc, 'A' + esel);
3941 else
3942 printf(" |%c", 'A' + esel);
3943 new_cc = 0;
3944 printf(" %016llx %04x %s %c%c AS%c",
3945 mas2 & ~0x3ffull,
3946 (mas1 >> 16) & 0x3fff,
3947 pgsz_names[(mas1 >> 7) & 0x1f],
3948 mas1 & MAS1_IND ? 'I' : ' ',
3949 mas1 & MAS1_IPROT ? 'P' : ' ',
3950 mas1 & MAS1_TS ? '1' : '0');
3951 printf(" %c%c%c%c%c%c%c",
3952 mas2 & MAS2_X0 ? 'a' : ' ',
3953 mas2 & MAS2_X1 ? 'v' : ' ',
3954 mas2 & MAS2_W ? 'w' : ' ',
3955 mas2 & MAS2_I ? 'i' : ' ',
3956 mas2 & MAS2_M ? 'm' : ' ',
3957 mas2 & MAS2_G ? 'g' : ' ',
3958 mas2 & MAS2_E ? 'e' : ' ');
3959 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3960 if (mas1 & MAS1_IND)
3961 printf(" %s\n",
3962 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3963 else
3964 printf(" U%c%c%c S%c%c%c\n",
3965 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3966 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3967 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3968 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3969 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3970 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3971 }
3972 }
3973}
3974#endif
3975
3976static void xmon_init(int enable)
3977{
3978 if (enable) {
3979 __debugger = xmon;
3980 __debugger_ipi = xmon_ipi;
3981 __debugger_bpt = xmon_bpt;
3982 __debugger_sstep = xmon_sstep;
3983 __debugger_iabr_match = xmon_iabr_match;
3984 __debugger_break_match = xmon_break_match;
3985 __debugger_fault_handler = xmon_fault_handler;
3986
3987#ifdef CONFIG_PPC_PSERIES
3988
3989
3990
3991
3992 set_indicator_token = rtas_token("set-indicator");
3993#endif
3994 } else {
3995 __debugger = NULL;
3996 __debugger_ipi = NULL;
3997 __debugger_bpt = NULL;
3998 __debugger_sstep = NULL;
3999 __debugger_iabr_match = NULL;
4000 __debugger_break_match = NULL;
4001 __debugger_fault_handler = NULL;
4002 }
4003}
4004
4005#ifdef CONFIG_MAGIC_SYSRQ
4006static void sysrq_handle_xmon(int key)
4007{
4008 if (xmon_is_locked_down()) {
4009 clear_all_bpt();
4010 xmon_init(0);
4011 return;
4012 }
4013
4014 xmon_init(1);
4015 debugger(get_irq_regs());
4016 if (!xmon_on)
4017 xmon_init(0);
4018}
4019
4020static const struct sysrq_key_op sysrq_xmon_op = {
4021 .handler = sysrq_handle_xmon,
4022 .help_msg = "xmon(x)",
4023 .action_msg = "Entering xmon",
4024};
4025
4026static int __init setup_xmon_sysrq(void)
4027{
4028 register_sysrq_key('x', &sysrq_xmon_op);
4029 return 0;
4030}
4031device_initcall(setup_xmon_sysrq);
4032#endif
4033
4034static void clear_all_bpt(void)
4035{
4036 int i;
4037
4038
4039 remove_bpts();
4040 remove_cpu_bpts();
4041
4042
4043 for (i = 0; i < NBPTS; ++i)
4044 bpts[i].enabled = 0;
4045
4046
4047 iabr = NULL;
4048 for (i = 0; i < nr_wp_slots(); i++)
4049 dabr[i].enabled = 0;
4050}
4051
4052#ifdef CONFIG_DEBUG_FS
4053static int xmon_dbgfs_set(void *data, u64 val)
4054{
4055 xmon_on = !!val;
4056 xmon_init(xmon_on);
4057
4058
4059 if (!xmon_on) {
4060 clear_all_bpt();
4061 get_output_lock();
4062 printf("xmon: All breakpoints cleared\n");
4063 release_output_lock();
4064 }
4065
4066 return 0;
4067}
4068
4069static int xmon_dbgfs_get(void *data, u64 *val)
4070{
4071 *val = xmon_on;
4072 return 0;
4073}
4074
4075DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
4076 xmon_dbgfs_set, "%llu\n");
4077
4078static int __init setup_xmon_dbgfs(void)
4079{
4080 debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
4081 &xmon_dbgfs_ops);
4082 return 0;
4083}
4084device_initcall(setup_xmon_dbgfs);
4085#endif
4086
4087static int xmon_early __initdata;
4088
4089static int __init early_parse_xmon(char *p)
4090{
4091 if (xmon_is_locked_down()) {
4092 xmon_init(0);
4093 xmon_early = 0;
4094 xmon_on = 0;
4095 } else if (!p || strncmp(p, "early", 5) == 0) {
4096
4097 xmon_init(1);
4098 xmon_early = 1;
4099 xmon_on = 1;
4100 } else if (strncmp(p, "on", 2) == 0) {
4101 xmon_init(1);
4102 xmon_on = 1;
4103 } else if (strncmp(p, "rw", 2) == 0) {
4104 xmon_init(1);
4105 xmon_on = 1;
4106 xmon_is_ro = false;
4107 } else if (strncmp(p, "ro", 2) == 0) {
4108 xmon_init(1);
4109 xmon_on = 1;
4110 xmon_is_ro = true;
4111 } else if (strncmp(p, "off", 3) == 0)
4112 xmon_on = 0;
4113 else
4114 return 1;
4115
4116 return 0;
4117}
4118early_param("xmon", early_parse_xmon);
4119
4120void __init xmon_setup(void)
4121{
4122 if (xmon_on)
4123 xmon_init(1);
4124 if (xmon_early)
4125 debugger(NULL);
4126}
4127
4128#ifdef CONFIG_SPU_BASE
4129
4130struct spu_info {
4131 struct spu *spu;
4132 u64 saved_mfc_sr1_RW;
4133 u32 saved_spu_runcntl_RW;
4134 unsigned long dump_addr;
4135 u8 stopped_ok;
4136};
4137
4138#define XMON_NUM_SPUS 16
4139
4140static struct spu_info spu_info[XMON_NUM_SPUS];
4141
4142void xmon_register_spus(struct list_head *list)
4143{
4144 struct spu *spu;
4145
4146 list_for_each_entry(spu, list, full_list) {
4147 if (spu->number >= XMON_NUM_SPUS) {
4148 WARN_ON(1);
4149 continue;
4150 }
4151
4152 spu_info[spu->number].spu = spu;
4153 spu_info[spu->number].stopped_ok = 0;
4154 spu_info[spu->number].dump_addr = (unsigned long)
4155 spu_info[spu->number].spu->local_store;
4156 }
4157}
4158
4159static void stop_spus(void)
4160{
4161 struct spu *spu;
4162 volatile int i;
4163 u64 tmp;
4164
4165 for (i = 0; i < XMON_NUM_SPUS; i++) {
4166 if (!spu_info[i].spu)
4167 continue;
4168
4169 if (setjmp(bus_error_jmp) == 0) {
4170 catch_memory_errors = 1;
4171 sync();
4172
4173 spu = spu_info[i].spu;
4174
4175 spu_info[i].saved_spu_runcntl_RW =
4176 in_be32(&spu->problem->spu_runcntl_RW);
4177
4178 tmp = spu_mfc_sr1_get(spu);
4179 spu_info[i].saved_mfc_sr1_RW = tmp;
4180
4181 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
4182 spu_mfc_sr1_set(spu, tmp);
4183
4184 sync();
4185 __delay(200);
4186
4187 spu_info[i].stopped_ok = 1;
4188
4189 printf("Stopped spu %.2d (was %s)\n", i,
4190 spu_info[i].saved_spu_runcntl_RW ?
4191 "running" : "stopped");
4192 } else {
4193 catch_memory_errors = 0;
4194 printf("*** Error stopping spu %.2d\n", i);
4195 }
4196 catch_memory_errors = 0;
4197 }
4198}
4199
4200static void restart_spus(void)
4201{
4202 struct spu *spu;
4203 volatile int i;
4204
4205 for (i = 0; i < XMON_NUM_SPUS; i++) {
4206 if (!spu_info[i].spu)
4207 continue;
4208
4209 if (!spu_info[i].stopped_ok) {
4210 printf("*** Error, spu %d was not successfully stopped"
4211 ", not restarting\n", i);
4212 continue;
4213 }
4214
4215 if (setjmp(bus_error_jmp) == 0) {
4216 catch_memory_errors = 1;
4217 sync();
4218
4219 spu = spu_info[i].spu;
4220 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
4221 out_be32(&spu->problem->spu_runcntl_RW,
4222 spu_info[i].saved_spu_runcntl_RW);
4223
4224 sync();
4225 __delay(200);
4226
4227 printf("Restarted spu %.2d\n", i);
4228 } else {
4229 catch_memory_errors = 0;
4230 printf("*** Error restarting spu %.2d\n", i);
4231 }
4232 catch_memory_errors = 0;
4233 }
4234}
4235
4236#define DUMP_WIDTH 23
4237#define DUMP_VALUE(format, field, value) \
4238do { \
4239 if (setjmp(bus_error_jmp) == 0) { \
4240 catch_memory_errors = 1; \
4241 sync(); \
4242 printf(" %-*s = "format"\n", DUMP_WIDTH, \
4243 #field, value); \
4244 sync(); \
4245 __delay(200); \
4246 } else { \
4247 catch_memory_errors = 0; \
4248 printf(" %-*s = *** Error reading field.\n", \
4249 DUMP_WIDTH, #field); \
4250 } \
4251 catch_memory_errors = 0; \
4252} while (0)
4253
4254#define DUMP_FIELD(obj, format, field) \
4255 DUMP_VALUE(format, field, obj->field)
4256
4257static void dump_spu_fields(struct spu *spu)
4258{
4259 printf("Dumping spu fields at address %p:\n", spu);
4260
4261 DUMP_FIELD(spu, "0x%x", number);
4262 DUMP_FIELD(spu, "%s", name);
4263 DUMP_FIELD(spu, "0x%lx", local_store_phys);
4264 DUMP_FIELD(spu, "0x%p", local_store);
4265 DUMP_FIELD(spu, "0x%lx", ls_size);
4266 DUMP_FIELD(spu, "0x%x", node);
4267 DUMP_FIELD(spu, "0x%lx", flags);
4268 DUMP_FIELD(spu, "%llu", class_0_pending);
4269 DUMP_FIELD(spu, "0x%llx", class_0_dar);
4270 DUMP_FIELD(spu, "0x%llx", class_1_dar);
4271 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
4272 DUMP_FIELD(spu, "0x%x", irqs[0]);
4273 DUMP_FIELD(spu, "0x%x", irqs[1]);
4274 DUMP_FIELD(spu, "0x%x", irqs[2]);
4275 DUMP_FIELD(spu, "0x%x", slb_replace);
4276 DUMP_FIELD(spu, "%d", pid);
4277 DUMP_FIELD(spu, "0x%p", mm);
4278 DUMP_FIELD(spu, "0x%p", ctx);
4279 DUMP_FIELD(spu, "0x%p", rq);
4280 DUMP_FIELD(spu, "0x%llx", timestamp);
4281 DUMP_FIELD(spu, "0x%lx", problem_phys);
4282 DUMP_FIELD(spu, "0x%p", problem);
4283 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
4284 in_be32(&spu->problem->spu_runcntl_RW));
4285 DUMP_VALUE("0x%x", problem->spu_status_R,
4286 in_be32(&spu->problem->spu_status_R));
4287 DUMP_VALUE("0x%x", problem->spu_npc_RW,
4288 in_be32(&spu->problem->spu_npc_RW));
4289 DUMP_FIELD(spu, "0x%p", priv2);
4290 DUMP_FIELD(spu, "0x%p", pdata);
4291}
4292
4293static int spu_inst_dump(unsigned long adr, long count, int praddr)
4294{
4295 return generic_inst_dump(adr, count, praddr, print_insn_spu);
4296}
4297
4298static void dump_spu_ls(unsigned long num, int subcmd)
4299{
4300 unsigned long offset, addr, ls_addr;
4301
4302 if (setjmp(bus_error_jmp) == 0) {
4303 catch_memory_errors = 1;
4304 sync();
4305 ls_addr = (unsigned long)spu_info[num].spu->local_store;
4306 sync();
4307 __delay(200);
4308 } else {
4309 catch_memory_errors = 0;
4310 printf("*** Error: accessing spu info for spu %ld\n", num);
4311 return;
4312 }
4313 catch_memory_errors = 0;
4314
4315 if (scanhex(&offset))
4316 addr = ls_addr + offset;
4317 else
4318 addr = spu_info[num].dump_addr;
4319
4320 if (addr >= ls_addr + LS_SIZE) {
4321 printf("*** Error: address outside of local store\n");
4322 return;
4323 }
4324
4325 switch (subcmd) {
4326 case 'i':
4327 addr += spu_inst_dump(addr, 16, 1);
4328 last_cmd = "sdi\n";
4329 break;
4330 default:
4331 prdump(addr, 64);
4332 addr += 64;
4333 last_cmd = "sd\n";
4334 break;
4335 }
4336
4337 spu_info[num].dump_addr = addr;
4338}
4339
4340static int do_spu_cmd(void)
4341{
4342 static unsigned long num = 0;
4343 int cmd, subcmd = 0;
4344
4345 cmd = inchar();
4346 switch (cmd) {
4347 case 's':
4348 stop_spus();
4349 break;
4350 case 'r':
4351 restart_spus();
4352 break;
4353 case 'd':
4354 subcmd = inchar();
4355 if (isxdigit(subcmd) || subcmd == '\n')
4356 termch = subcmd;
4357 fallthrough;
4358 case 'f':
4359 scanhex(&num);
4360 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
4361 printf("*** Error: invalid spu number\n");
4362 return 0;
4363 }
4364
4365 switch (cmd) {
4366 case 'f':
4367 dump_spu_fields(spu_info[num].spu);
4368 break;
4369 default:
4370 dump_spu_ls(num, subcmd);
4371 break;
4372 }
4373
4374 break;
4375 default:
4376 return -1;
4377 }
4378
4379 return 0;
4380}
4381#else
4382static int do_spu_cmd(void)
4383{
4384 return -1;
4385}
4386#endif
4387