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