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