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