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