[PATCH] briq_panel: read() and write() get __user pointers, damnit
[linux-2.6/verdex.git] / arch / powerpc / xmon / xmon.c
blob8adad1444a51f3fca949bc4d0e7ec3ead0f3d93e
1 /*
2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996-2005 Paul Mackerras.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/smp.h>
14 #include <linux/mm.h>
15 #include <linux/reboot.h>
16 #include <linux/delay.h>
17 #include <linux/kallsyms.h>
18 #include <linux/cpumask.h>
19 #include <linux/module.h>
20 #include <linux/sysrq.h>
21 #include <linux/interrupt.h>
23 #include <asm/ptrace.h>
24 #include <asm/string.h>
25 #include <asm/prom.h>
26 #include <asm/machdep.h>
27 #include <asm/xmon.h>
28 #include <asm/processor.h>
29 #include <asm/pgtable.h>
30 #include <asm/mmu.h>
31 #include <asm/mmu_context.h>
32 #include <asm/cputable.h>
33 #include <asm/rtas.h>
34 #include <asm/sstep.h>
35 #include <asm/bug.h>
37 #ifdef CONFIG_PPC64
38 #include <asm/hvcall.h>
39 #include <asm/paca.h>
40 #endif
42 #include "nonstdio.h"
44 #define scanhex xmon_scanhex
45 #define skipbl xmon_skipbl
47 #ifdef CONFIG_SMP
48 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
49 static unsigned long xmon_taken = 1;
50 static int xmon_owner;
51 static int xmon_gate;
52 #endif /* CONFIG_SMP */
54 static unsigned long in_xmon = 0;
56 static unsigned long adrs;
57 static int size = 1;
58 #define MAX_DUMP (128 * 1024)
59 static unsigned long ndump = 64;
60 static unsigned long nidump = 16;
61 static unsigned long ncsum = 4096;
62 static int termch;
63 static char tmpstr[128];
65 #define JMP_BUF_LEN 23
66 static long bus_error_jmp[JMP_BUF_LEN];
67 static int catch_memory_errors;
68 static long *xmon_fault_jmp[NR_CPUS];
69 #define setjmp xmon_setjmp
70 #define longjmp xmon_longjmp
72 /* Breakpoint stuff */
73 struct bpt {
74 unsigned long address;
75 unsigned int instr[2];
76 atomic_t ref_count;
77 int enabled;
78 unsigned long pad;
81 /* Bits in bpt.enabled */
82 #define BP_IABR_TE 1 /* IABR translation enabled */
83 #define BP_IABR 2
84 #define BP_TRAP 8
85 #define BP_DABR 0x10
87 #define NBPTS 256
88 static struct bpt bpts[NBPTS];
89 static struct bpt dabr;
90 static struct bpt *iabr;
91 static unsigned bpinstr = 0x7fe00008; /* trap */
93 #define BP_NUM(bp) ((bp) - bpts + 1)
95 /* Prototypes */
96 static int cmds(struct pt_regs *);
97 static int mread(unsigned long, void *, int);
98 static int mwrite(unsigned long, void *, int);
99 static int handle_fault(struct pt_regs *);
100 static void byterev(unsigned char *, int);
101 static void memex(void);
102 static int bsesc(void);
103 static void dump(void);
104 static void prdump(unsigned long, long);
105 static int ppc_inst_dump(unsigned long, long, int);
106 void print_address(unsigned long);
107 static void backtrace(struct pt_regs *);
108 static void excprint(struct pt_regs *);
109 static void prregs(struct pt_regs *);
110 static void memops(int);
111 static void memlocate(void);
112 static void memzcan(void);
113 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
114 int skipbl(void);
115 int scanhex(unsigned long *valp);
116 static void scannl(void);
117 static int hexdigit(int);
118 void getstring(char *, int);
119 static void flush_input(void);
120 static int inchar(void);
121 static void take_input(char *);
122 static unsigned long read_spr(int);
123 static void write_spr(int, unsigned long);
124 static void super_regs(void);
125 static void remove_bpts(void);
126 static void insert_bpts(void);
127 static void remove_cpu_bpts(void);
128 static void insert_cpu_bpts(void);
129 static struct bpt *at_breakpoint(unsigned long pc);
130 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
131 static int do_step(struct pt_regs *);
132 static void bpt_cmds(void);
133 static void cacheflush(void);
134 static int cpu_cmd(void);
135 static void csum(void);
136 static void bootcmds(void);
137 static void proccall(void);
138 void dump_segments(void);
139 static void symbol_lookup(void);
140 static void xmon_show_stack(unsigned long sp, unsigned long lr,
141 unsigned long pc);
142 static void xmon_print_symbol(unsigned long address, const char *mid,
143 const char *after);
144 static const char *getvecname(unsigned long vec);
146 int xmon_no_auto_backtrace;
148 extern int print_insn_powerpc(unsigned long, unsigned long, int);
150 extern void xmon_enter(void);
151 extern void xmon_leave(void);
153 extern long setjmp(long *);
154 extern void longjmp(long *, long);
155 extern void xmon_save_regs(struct pt_regs *);
157 #ifdef CONFIG_PPC64
158 #define REG "%.16lx"
159 #define REGS_PER_LINE 4
160 #define LAST_VOLATILE 13
161 #else
162 #define REG "%.8lx"
163 #define REGS_PER_LINE 8
164 #define LAST_VOLATILE 12
165 #endif
167 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
169 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
170 || ('a' <= (c) && (c) <= 'f') \
171 || ('A' <= (c) && (c) <= 'F'))
172 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
173 || ('a' <= (c) && (c) <= 'z') \
174 || ('A' <= (c) && (c) <= 'Z'))
175 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
177 static char *help_string = "\
178 Commands:\n\
179 b show breakpoints\n\
180 bd set data breakpoint\n\
181 bi set instruction breakpoint\n\
182 bc clear breakpoint\n"
183 #ifdef CONFIG_SMP
185 c print cpus stopped in xmon\n\
186 c# try to switch to cpu number h (in hex)\n"
187 #endif
189 C checksum\n\
190 d dump bytes\n\
191 di dump instructions\n\
192 df dump float values\n\
193 dd dump double values\n\
194 dr dump stream of raw bytes\n\
195 e print exception information\n\
196 f flush cache\n\
197 la lookup symbol+offset of specified address\n\
198 ls lookup address of specified symbol\n\
199 m examine/change memory\n\
200 mm move a block of memory\n\
201 ms set a block of memory\n\
202 md compare two blocks of memory\n\
203 ml locate a block of memory\n\
204 mz zero a block of memory\n\
205 mi show information about memory allocation\n\
206 p call a procedure\n\
207 r print registers\n\
208 s single step\n\
209 S print special registers\n\
210 t print backtrace\n\
211 x exit monitor and recover\n\
212 X exit monitor and dont recover\n"
213 #ifdef CONFIG_PPC64
214 " u dump segment table or SLB\n"
215 #endif
216 #ifdef CONFIG_PPC_STD_MMU_32
217 " u dump segment registers\n"
218 #endif
219 " ? help\n"
220 " zr reboot\n\
221 zh halt\n"
224 static struct pt_regs *xmon_regs;
226 static inline void sync(void)
228 asm volatile("sync; isync");
231 static inline void store_inst(void *p)
233 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
236 static inline void cflush(void *p)
238 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
241 static inline void cinval(void *p)
243 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
247 * Disable surveillance (the service processor watchdog function)
248 * while we are in xmon.
249 * XXX we should re-enable it when we leave. :)
251 #define SURVEILLANCE_TOKEN 9000
253 static inline void disable_surveillance(void)
255 #ifdef CONFIG_PPC_PSERIES
256 /* Since this can't be a module, args should end up below 4GB. */
257 static struct rtas_args args;
260 * At this point we have got all the cpus we can into
261 * xmon, so there is hopefully no other cpu calling RTAS
262 * at the moment, even though we don't take rtas.lock.
263 * If we did try to take rtas.lock there would be a
264 * real possibility of deadlock.
266 args.token = rtas_token("set-indicator");
267 if (args.token == RTAS_UNKNOWN_SERVICE)
268 return;
269 args.nargs = 3;
270 args.nret = 1;
271 args.rets = &args.args[3];
272 args.args[0] = SURVEILLANCE_TOKEN;
273 args.args[1] = 0;
274 args.args[2] = 0;
275 enter_rtas(__pa(&args));
276 #endif /* CONFIG_PPC_PSERIES */
279 #ifdef CONFIG_SMP
280 static int xmon_speaker;
282 static void get_output_lock(void)
284 int me = smp_processor_id() + 0x100;
285 int last_speaker = 0, prev;
286 long timeout;
288 if (xmon_speaker == me)
289 return;
290 for (;;) {
291 if (xmon_speaker == 0) {
292 last_speaker = cmpxchg(&xmon_speaker, 0, me);
293 if (last_speaker == 0)
294 return;
296 timeout = 10000000;
297 while (xmon_speaker == last_speaker) {
298 if (--timeout > 0)
299 continue;
300 /* hostile takeover */
301 prev = cmpxchg(&xmon_speaker, last_speaker, me);
302 if (prev == last_speaker)
303 return;
304 break;
309 static void release_output_lock(void)
311 xmon_speaker = 0;
313 #endif
315 static int xmon_core(struct pt_regs *regs, int fromipi)
317 int cmd = 0;
318 unsigned long msr;
319 struct bpt *bp;
320 long recurse_jmp[JMP_BUF_LEN];
321 unsigned long offset;
322 #ifdef CONFIG_SMP
323 int cpu;
324 int secondary;
325 unsigned long timeout;
326 #endif
328 msr = mfmsr();
329 mtmsr(msr & ~MSR_EE); /* disable interrupts */
331 bp = in_breakpoint_table(regs->nip, &offset);
332 if (bp != NULL) {
333 regs->nip = bp->address + offset;
334 atomic_dec(&bp->ref_count);
337 remove_cpu_bpts();
339 #ifdef CONFIG_SMP
340 cpu = smp_processor_id();
341 if (cpu_isset(cpu, cpus_in_xmon)) {
342 get_output_lock();
343 excprint(regs);
344 printf("cpu 0x%x: Exception %lx %s in xmon, "
345 "returning to main loop\n",
346 cpu, regs->trap, getvecname(TRAP(regs)));
347 release_output_lock();
348 longjmp(xmon_fault_jmp[cpu], 1);
351 if (setjmp(recurse_jmp) != 0) {
352 if (!in_xmon || !xmon_gate) {
353 get_output_lock();
354 printf("xmon: WARNING: bad recursive fault "
355 "on cpu 0x%x\n", cpu);
356 release_output_lock();
357 goto waiting;
359 secondary = !(xmon_taken && cpu == xmon_owner);
360 goto cmdloop;
363 xmon_fault_jmp[cpu] = recurse_jmp;
364 cpu_set(cpu, cpus_in_xmon);
366 bp = NULL;
367 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
368 bp = at_breakpoint(regs->nip);
369 if (bp || (regs->msr & MSR_RI) == 0)
370 fromipi = 0;
372 if (!fromipi) {
373 get_output_lock();
374 excprint(regs);
375 if (bp) {
376 printf("cpu 0x%x stopped at breakpoint 0x%x (",
377 cpu, BP_NUM(bp));
378 xmon_print_symbol(regs->nip, " ", ")\n");
380 if ((regs->msr & MSR_RI) == 0)
381 printf("WARNING: exception is not recoverable, "
382 "can't continue\n");
383 release_output_lock();
386 waiting:
387 secondary = 1;
388 while (secondary && !xmon_gate) {
389 if (in_xmon == 0) {
390 if (fromipi)
391 goto leave;
392 secondary = test_and_set_bit(0, &in_xmon);
394 barrier();
397 if (!secondary && !xmon_gate) {
398 /* we are the first cpu to come in */
399 /* interrupt other cpu(s) */
400 int ncpus = num_online_cpus();
402 xmon_owner = cpu;
403 mb();
404 if (ncpus > 1) {
405 smp_send_debugger_break(MSG_ALL_BUT_SELF);
406 /* wait for other cpus to come in */
407 for (timeout = 100000000; timeout != 0; --timeout) {
408 if (cpus_weight(cpus_in_xmon) >= ncpus)
409 break;
410 barrier();
413 remove_bpts();
414 disable_surveillance();
415 /* for breakpoint or single step, print the current instr. */
416 if (bp || TRAP(regs) == 0xd00)
417 ppc_inst_dump(regs->nip, 1, 0);
418 printf("enter ? for help\n");
419 mb();
420 xmon_gate = 1;
421 barrier();
424 cmdloop:
425 while (in_xmon) {
426 if (secondary) {
427 if (cpu == xmon_owner) {
428 if (!test_and_set_bit(0, &xmon_taken)) {
429 secondary = 0;
430 continue;
432 /* missed it */
433 while (cpu == xmon_owner)
434 barrier();
436 barrier();
437 } else {
438 cmd = cmds(regs);
439 if (cmd != 0) {
440 /* exiting xmon */
441 insert_bpts();
442 xmon_gate = 0;
443 wmb();
444 in_xmon = 0;
445 break;
447 /* have switched to some other cpu */
448 secondary = 1;
451 leave:
452 cpu_clear(cpu, cpus_in_xmon);
453 xmon_fault_jmp[cpu] = NULL;
454 #else
455 /* UP is simple... */
456 if (in_xmon) {
457 printf("Exception %lx %s in xmon, returning to main loop\n",
458 regs->trap, getvecname(TRAP(regs)));
459 longjmp(xmon_fault_jmp[0], 1);
461 if (setjmp(recurse_jmp) == 0) {
462 xmon_fault_jmp[0] = recurse_jmp;
463 in_xmon = 1;
465 excprint(regs);
466 bp = at_breakpoint(regs->nip);
467 if (bp) {
468 printf("Stopped at breakpoint %x (", BP_NUM(bp));
469 xmon_print_symbol(regs->nip, " ", ")\n");
471 if ((regs->msr & MSR_RI) == 0)
472 printf("WARNING: exception is not recoverable, "
473 "can't continue\n");
474 remove_bpts();
475 disable_surveillance();
476 /* for breakpoint or single step, print the current instr. */
477 if (bp || TRAP(regs) == 0xd00)
478 ppc_inst_dump(regs->nip, 1, 0);
479 printf("enter ? for help\n");
482 cmd = cmds(regs);
484 insert_bpts();
485 in_xmon = 0;
486 #endif
488 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
489 bp = at_breakpoint(regs->nip);
490 if (bp != NULL) {
491 int stepped = emulate_step(regs, bp->instr[0]);
492 if (stepped == 0) {
493 regs->nip = (unsigned long) &bp->instr[0];
494 atomic_inc(&bp->ref_count);
495 } else if (stepped < 0) {
496 printf("Couldn't single-step %s instruction\n",
497 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
502 insert_cpu_bpts();
504 mtmsr(msr); /* restore interrupt enable */
506 return cmd != 'X';
509 int xmon(struct pt_regs *excp)
511 struct pt_regs regs;
513 if (excp == NULL) {
514 xmon_save_regs(&regs);
515 excp = &regs;
517 return xmon_core(excp, 0);
519 EXPORT_SYMBOL(xmon);
521 irqreturn_t
522 xmon_irq(int irq, void *d, struct pt_regs *regs)
524 unsigned long flags;
525 local_irq_save(flags);
526 printf("Keyboard interrupt\n");
527 xmon(regs);
528 local_irq_restore(flags);
529 return IRQ_HANDLED;
532 static int xmon_bpt(struct pt_regs *regs)
534 struct bpt *bp;
535 unsigned long offset;
537 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
538 return 0;
540 /* Are we at the trap at bp->instr[1] for some bp? */
541 bp = in_breakpoint_table(regs->nip, &offset);
542 if (bp != NULL && offset == 4) {
543 regs->nip = bp->address + 4;
544 atomic_dec(&bp->ref_count);
545 return 1;
548 /* Are we at a breakpoint? */
549 bp = at_breakpoint(regs->nip);
550 if (!bp)
551 return 0;
553 xmon_core(regs, 0);
555 return 1;
558 static int xmon_sstep(struct pt_regs *regs)
560 if (user_mode(regs))
561 return 0;
562 xmon_core(regs, 0);
563 return 1;
566 static int xmon_dabr_match(struct pt_regs *regs)
568 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
569 return 0;
570 if (dabr.enabled == 0)
571 return 0;
572 xmon_core(regs, 0);
573 return 1;
576 static int xmon_iabr_match(struct pt_regs *regs)
578 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
579 return 0;
580 if (iabr == 0)
581 return 0;
582 xmon_core(regs, 0);
583 return 1;
586 static int xmon_ipi(struct pt_regs *regs)
588 #ifdef CONFIG_SMP
589 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
590 xmon_core(regs, 1);
591 #endif
592 return 0;
595 static int xmon_fault_handler(struct pt_regs *regs)
597 struct bpt *bp;
598 unsigned long offset;
600 if (in_xmon && catch_memory_errors)
601 handle_fault(regs); /* doesn't return */
603 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
604 bp = in_breakpoint_table(regs->nip, &offset);
605 if (bp != NULL) {
606 regs->nip = bp->address + offset;
607 atomic_dec(&bp->ref_count);
611 return 0;
614 static struct bpt *at_breakpoint(unsigned long pc)
616 int i;
617 struct bpt *bp;
619 bp = bpts;
620 for (i = 0; i < NBPTS; ++i, ++bp)
621 if (bp->enabled && pc == bp->address)
622 return bp;
623 return NULL;
626 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
628 unsigned long off;
630 off = nip - (unsigned long) bpts;
631 if (off >= sizeof(bpts))
632 return NULL;
633 off %= sizeof(struct bpt);
634 if (off != offsetof(struct bpt, instr[0])
635 && off != offsetof(struct bpt, instr[1]))
636 return NULL;
637 *offp = off - offsetof(struct bpt, instr[0]);
638 return (struct bpt *) (nip - off);
641 static struct bpt *new_breakpoint(unsigned long a)
643 struct bpt *bp;
645 a &= ~3UL;
646 bp = at_breakpoint(a);
647 if (bp)
648 return bp;
650 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
651 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
652 bp->address = a;
653 bp->instr[1] = bpinstr;
654 store_inst(&bp->instr[1]);
655 return bp;
659 printf("Sorry, no free breakpoints. Please clear one first.\n");
660 return NULL;
663 static void insert_bpts(void)
665 int i;
666 struct bpt *bp;
668 bp = bpts;
669 for (i = 0; i < NBPTS; ++i, ++bp) {
670 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
671 continue;
672 if (mread(bp->address, &bp->instr[0], 4) != 4) {
673 printf("Couldn't read instruction at %lx, "
674 "disabling breakpoint there\n", bp->address);
675 bp->enabled = 0;
676 continue;
678 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
679 printf("Breakpoint at %lx is on an mtmsrd or rfid "
680 "instruction, disabling it\n", bp->address);
681 bp->enabled = 0;
682 continue;
684 store_inst(&bp->instr[0]);
685 if (bp->enabled & BP_IABR)
686 continue;
687 if (mwrite(bp->address, &bpinstr, 4) != 4) {
688 printf("Couldn't write instruction at %lx, "
689 "disabling breakpoint there\n", bp->address);
690 bp->enabled &= ~BP_TRAP;
691 continue;
693 store_inst((void *)bp->address);
697 static void insert_cpu_bpts(void)
699 if (dabr.enabled)
700 set_dabr(dabr.address | (dabr.enabled & 7));
701 if (iabr && cpu_has_feature(CPU_FTR_IABR))
702 mtspr(SPRN_IABR, iabr->address
703 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
706 static void remove_bpts(void)
708 int i;
709 struct bpt *bp;
710 unsigned instr;
712 bp = bpts;
713 for (i = 0; i < NBPTS; ++i, ++bp) {
714 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
715 continue;
716 if (mread(bp->address, &instr, 4) == 4
717 && instr == bpinstr
718 && mwrite(bp->address, &bp->instr, 4) != 4)
719 printf("Couldn't remove breakpoint at %lx\n",
720 bp->address);
721 else
722 store_inst((void *)bp->address);
726 static void remove_cpu_bpts(void)
728 set_dabr(0);
729 if (cpu_has_feature(CPU_FTR_IABR))
730 mtspr(SPRN_IABR, 0);
733 /* Command interpreting routine */
734 static char *last_cmd;
736 static int
737 cmds(struct pt_regs *excp)
739 int cmd = 0;
741 last_cmd = NULL;
742 xmon_regs = excp;
744 if (!xmon_no_auto_backtrace) {
745 xmon_no_auto_backtrace = 1;
746 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
749 for(;;) {
750 #ifdef CONFIG_SMP
751 printf("%x:", smp_processor_id());
752 #endif /* CONFIG_SMP */
753 printf("mon> ");
754 flush_input();
755 termch = 0;
756 cmd = skipbl();
757 if( cmd == '\n' ) {
758 if (last_cmd == NULL)
759 continue;
760 take_input(last_cmd);
761 last_cmd = NULL;
762 cmd = inchar();
764 switch (cmd) {
765 case 'm':
766 cmd = inchar();
767 switch (cmd) {
768 case 'm':
769 case 's':
770 case 'd':
771 memops(cmd);
772 break;
773 case 'l':
774 memlocate();
775 break;
776 case 'z':
777 memzcan();
778 break;
779 case 'i':
780 show_mem();
781 break;
782 default:
783 termch = cmd;
784 memex();
786 break;
787 case 'd':
788 dump();
789 break;
790 case 'l':
791 symbol_lookup();
792 break;
793 case 'r':
794 prregs(excp); /* print regs */
795 break;
796 case 'e':
797 excprint(excp);
798 break;
799 case 'S':
800 super_regs();
801 break;
802 case 't':
803 backtrace(excp);
804 break;
805 case 'f':
806 cacheflush();
807 break;
808 case 's':
809 if (do_step(excp))
810 return cmd;
811 break;
812 case 'x':
813 case 'X':
814 return cmd;
815 case EOF:
816 printf(" <no input ...>\n");
817 mdelay(2000);
818 return cmd;
819 case '?':
820 printf(help_string);
821 break;
822 case 'b':
823 bpt_cmds();
824 break;
825 case 'C':
826 csum();
827 break;
828 case 'c':
829 if (cpu_cmd())
830 return 0;
831 break;
832 case 'z':
833 bootcmds();
834 break;
835 case 'p':
836 proccall();
837 break;
838 #ifdef CONFIG_PPC_STD_MMU
839 case 'u':
840 dump_segments();
841 break;
842 #endif
843 default:
844 printf("Unrecognized command: ");
845 do {
846 if (' ' < cmd && cmd <= '~')
847 putchar(cmd);
848 else
849 printf("\\x%x", cmd);
850 cmd = inchar();
851 } while (cmd != '\n');
852 printf(" (type ? for help)\n");
853 break;
859 * Step a single instruction.
860 * Some instructions we emulate, others we execute with MSR_SE set.
862 static int do_step(struct pt_regs *regs)
864 unsigned int instr;
865 int stepped;
867 /* check we are in 64-bit kernel mode, translation enabled */
868 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
869 if (mread(regs->nip, &instr, 4) == 4) {
870 stepped = emulate_step(regs, instr);
871 if (stepped < 0) {
872 printf("Couldn't single-step %s instruction\n",
873 (IS_RFID(instr)? "rfid": "mtmsrd"));
874 return 0;
876 if (stepped > 0) {
877 regs->trap = 0xd00 | (regs->trap & 1);
878 printf("stepped to ");
879 xmon_print_symbol(regs->nip, " ", "\n");
880 ppc_inst_dump(regs->nip, 1, 0);
881 return 0;
885 regs->msr |= MSR_SE;
886 return 1;
889 static void bootcmds(void)
891 int cmd;
893 cmd = inchar();
894 if (cmd == 'r')
895 ppc_md.restart(NULL);
896 else if (cmd == 'h')
897 ppc_md.halt();
898 else if (cmd == 'p')
899 ppc_md.power_off();
902 static int cpu_cmd(void)
904 #ifdef CONFIG_SMP
905 unsigned long cpu;
906 int timeout;
907 int count;
909 if (!scanhex(&cpu)) {
910 /* print cpus waiting or in xmon */
911 printf("cpus stopped:");
912 count = 0;
913 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
914 if (cpu_isset(cpu, cpus_in_xmon)) {
915 if (count == 0)
916 printf(" %x", cpu);
917 ++count;
918 } else {
919 if (count > 1)
920 printf("-%x", cpu - 1);
921 count = 0;
924 if (count > 1)
925 printf("-%x", NR_CPUS - 1);
926 printf("\n");
927 return 0;
929 /* try to switch to cpu specified */
930 if (!cpu_isset(cpu, cpus_in_xmon)) {
931 printf("cpu 0x%x isn't in xmon\n", cpu);
932 return 0;
934 xmon_taken = 0;
935 mb();
936 xmon_owner = cpu;
937 timeout = 10000000;
938 while (!xmon_taken) {
939 if (--timeout == 0) {
940 if (test_and_set_bit(0, &xmon_taken))
941 break;
942 /* take control back */
943 mb();
944 xmon_owner = smp_processor_id();
945 printf("cpu %u didn't take control\n", cpu);
946 return 0;
948 barrier();
950 return 1;
951 #else
952 return 0;
953 #endif /* CONFIG_SMP */
956 static unsigned short fcstab[256] = {
957 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
958 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
959 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
960 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
961 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
962 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
963 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
964 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
965 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
966 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
967 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
968 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
969 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
970 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
971 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
972 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
973 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
974 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
975 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
976 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
977 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
978 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
979 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
980 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
981 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
982 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
983 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
984 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
985 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
986 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
987 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
988 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
991 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
993 static void
994 csum(void)
996 unsigned int i;
997 unsigned short fcs;
998 unsigned char v;
1000 if (!scanhex(&adrs))
1001 return;
1002 if (!scanhex(&ncsum))
1003 return;
1004 fcs = 0xffff;
1005 for (i = 0; i < ncsum; ++i) {
1006 if (mread(adrs+i, &v, 1) == 0) {
1007 printf("csum stopped at %x\n", adrs+i);
1008 break;
1010 fcs = FCS(fcs, v);
1012 printf("%x\n", fcs);
1016 * Check if this is a suitable place to put a breakpoint.
1018 static long check_bp_loc(unsigned long addr)
1020 unsigned int instr;
1022 addr &= ~3;
1023 if (!is_kernel_addr(addr)) {
1024 printf("Breakpoints may only be placed at kernel addresses\n");
1025 return 0;
1027 if (!mread(addr, &instr, sizeof(instr))) {
1028 printf("Can't read instruction at address %lx\n", addr);
1029 return 0;
1031 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1032 printf("Breakpoints may not be placed on mtmsrd or rfid "
1033 "instructions\n");
1034 return 0;
1036 return 1;
1039 static char *breakpoint_help_string =
1040 "Breakpoint command usage:\n"
1041 "b show breakpoints\n"
1042 "b <addr> [cnt] set breakpoint at given instr addr\n"
1043 "bc clear all breakpoints\n"
1044 "bc <n/addr> clear breakpoint number n or at addr\n"
1045 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1046 "bd <addr> [cnt] set hardware data breakpoint\n"
1049 static void
1050 bpt_cmds(void)
1052 int cmd;
1053 unsigned long a;
1054 int mode, i;
1055 struct bpt *bp;
1056 const char badaddr[] = "Only kernel addresses are permitted "
1057 "for breakpoints\n";
1059 cmd = inchar();
1060 switch (cmd) {
1061 #ifndef CONFIG_8xx
1062 case 'd': /* bd - hardware data breakpoint */
1063 mode = 7;
1064 cmd = inchar();
1065 if (cmd == 'r')
1066 mode = 5;
1067 else if (cmd == 'w')
1068 mode = 6;
1069 else
1070 termch = cmd;
1071 dabr.address = 0;
1072 dabr.enabled = 0;
1073 if (scanhex(&dabr.address)) {
1074 if (!is_kernel_addr(dabr.address)) {
1075 printf(badaddr);
1076 break;
1078 dabr.address &= ~7;
1079 dabr.enabled = mode | BP_DABR;
1081 break;
1083 case 'i': /* bi - hardware instr breakpoint */
1084 if (!cpu_has_feature(CPU_FTR_IABR)) {
1085 printf("Hardware instruction breakpoint "
1086 "not supported on this cpu\n");
1087 break;
1089 if (iabr) {
1090 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1091 iabr = NULL;
1093 if (!scanhex(&a))
1094 break;
1095 if (!check_bp_loc(a))
1096 break;
1097 bp = new_breakpoint(a);
1098 if (bp != NULL) {
1099 bp->enabled |= BP_IABR | BP_IABR_TE;
1100 iabr = bp;
1102 break;
1103 #endif
1105 case 'c':
1106 if (!scanhex(&a)) {
1107 /* clear all breakpoints */
1108 for (i = 0; i < NBPTS; ++i)
1109 bpts[i].enabled = 0;
1110 iabr = NULL;
1111 dabr.enabled = 0;
1112 printf("All breakpoints cleared\n");
1113 break;
1116 if (a <= NBPTS && a >= 1) {
1117 /* assume a breakpoint number */
1118 bp = &bpts[a-1]; /* bp nums are 1 based */
1119 } else {
1120 /* assume a breakpoint address */
1121 bp = at_breakpoint(a);
1122 if (bp == 0) {
1123 printf("No breakpoint at %x\n", a);
1124 break;
1128 printf("Cleared breakpoint %x (", BP_NUM(bp));
1129 xmon_print_symbol(bp->address, " ", ")\n");
1130 bp->enabled = 0;
1131 break;
1133 default:
1134 termch = cmd;
1135 cmd = skipbl();
1136 if (cmd == '?') {
1137 printf(breakpoint_help_string);
1138 break;
1140 termch = cmd;
1141 if (!scanhex(&a)) {
1142 /* print all breakpoints */
1143 printf(" type address\n");
1144 if (dabr.enabled) {
1145 printf(" data "REG" [", dabr.address);
1146 if (dabr.enabled & 1)
1147 printf("r");
1148 if (dabr.enabled & 2)
1149 printf("w");
1150 printf("]\n");
1152 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1153 if (!bp->enabled)
1154 continue;
1155 printf("%2x %s ", BP_NUM(bp),
1156 (bp->enabled & BP_IABR)? "inst": "trap");
1157 xmon_print_symbol(bp->address, " ", "\n");
1159 break;
1162 if (!check_bp_loc(a))
1163 break;
1164 bp = new_breakpoint(a);
1165 if (bp != NULL)
1166 bp->enabled |= BP_TRAP;
1167 break;
1171 /* Very cheap human name for vector lookup. */
1172 static
1173 const char *getvecname(unsigned long vec)
1175 char *ret;
1177 switch (vec) {
1178 case 0x100: ret = "(System Reset)"; break;
1179 case 0x200: ret = "(Machine Check)"; break;
1180 case 0x300: ret = "(Data Access)"; break;
1181 case 0x380: ret = "(Data SLB Access)"; break;
1182 case 0x400: ret = "(Instruction Access)"; break;
1183 case 0x480: ret = "(Instruction SLB Access)"; break;
1184 case 0x500: ret = "(Hardware Interrupt)"; break;
1185 case 0x600: ret = "(Alignment)"; break;
1186 case 0x700: ret = "(Program Check)"; break;
1187 case 0x800: ret = "(FPU Unavailable)"; break;
1188 case 0x900: ret = "(Decrementer)"; break;
1189 case 0xc00: ret = "(System Call)"; break;
1190 case 0xd00: ret = "(Single Step)"; break;
1191 case 0xf00: ret = "(Performance Monitor)"; break;
1192 case 0xf20: ret = "(Altivec Unavailable)"; break;
1193 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1194 default: ret = "";
1196 return ret;
1199 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1200 unsigned long *endp)
1202 unsigned long size, offset;
1203 const char *name;
1204 char *modname;
1206 *startp = *endp = 0;
1207 if (pc == 0)
1208 return;
1209 if (setjmp(bus_error_jmp) == 0) {
1210 catch_memory_errors = 1;
1211 sync();
1212 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1213 if (name != NULL) {
1214 *startp = pc - offset;
1215 *endp = pc - offset + size;
1217 sync();
1219 catch_memory_errors = 0;
1222 static int xmon_depth_to_print = 64;
1224 #ifdef CONFIG_PPC64
1225 #define LRSAVE_OFFSET 0x10
1226 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1227 #define MARKER_OFFSET 0x60
1228 #define REGS_OFFSET 0x70
1229 #else
1230 #define LRSAVE_OFFSET 4
1231 #define REG_FRAME_MARKER 0x72656773
1232 #define MARKER_OFFSET 8
1233 #define REGS_OFFSET 16
1234 #endif
1236 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1237 unsigned long pc)
1239 unsigned long ip;
1240 unsigned long newsp;
1241 unsigned long marker;
1242 int count = 0;
1243 struct pt_regs regs;
1245 do {
1246 if (sp < PAGE_OFFSET) {
1247 if (sp != 0)
1248 printf("SP (%lx) is in userspace\n", sp);
1249 break;
1252 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1253 || !mread(sp, &newsp, sizeof(unsigned long))) {
1254 printf("Couldn't read stack frame at %lx\n", sp);
1255 break;
1259 * For the first stack frame, try to work out if
1260 * LR and/or the saved LR value in the bottommost
1261 * stack frame are valid.
1263 if ((pc | lr) != 0) {
1264 unsigned long fnstart, fnend;
1265 unsigned long nextip;
1266 int printip = 1;
1268 get_function_bounds(pc, &fnstart, &fnend);
1269 nextip = 0;
1270 if (newsp > sp)
1271 mread(newsp + LRSAVE_OFFSET, &nextip,
1272 sizeof(unsigned long));
1273 if (lr == ip) {
1274 if (lr < PAGE_OFFSET
1275 || (fnstart <= lr && lr < fnend))
1276 printip = 0;
1277 } else if (lr == nextip) {
1278 printip = 0;
1279 } else if (lr >= PAGE_OFFSET
1280 && !(fnstart <= lr && lr < fnend)) {
1281 printf("[link register ] ");
1282 xmon_print_symbol(lr, " ", "\n");
1284 if (printip) {
1285 printf("["REG"] ", sp);
1286 xmon_print_symbol(ip, " ", " (unreliable)\n");
1288 pc = lr = 0;
1290 } else {
1291 printf("["REG"] ", sp);
1292 xmon_print_symbol(ip, " ", "\n");
1295 /* Look for "regshere" marker to see if this is
1296 an exception frame. */
1297 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1298 && marker == REG_FRAME_MARKER) {
1299 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1300 != sizeof(regs)) {
1301 printf("Couldn't read registers at %lx\n",
1302 sp + REGS_OFFSET);
1303 break;
1305 printf("--- Exception: %lx %s at ", regs.trap,
1306 getvecname(TRAP(&regs)));
1307 pc = regs.nip;
1308 lr = regs.link;
1309 xmon_print_symbol(pc, " ", "\n");
1312 if (newsp == 0)
1313 break;
1315 sp = newsp;
1316 } while (count++ < xmon_depth_to_print);
1319 static void backtrace(struct pt_regs *excp)
1321 unsigned long sp;
1323 if (scanhex(&sp))
1324 xmon_show_stack(sp, 0, 0);
1325 else
1326 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1327 scannl();
1330 static void print_bug_trap(struct pt_regs *regs)
1332 struct bug_entry *bug;
1333 unsigned long addr;
1335 if (regs->msr & MSR_PR)
1336 return; /* not in kernel */
1337 addr = regs->nip; /* address of trap instruction */
1338 if (addr < PAGE_OFFSET)
1339 return;
1340 bug = find_bug(regs->nip);
1341 if (bug == NULL)
1342 return;
1343 if (bug->line & BUG_WARNING_TRAP)
1344 return;
1346 printf("kernel BUG in %s at %s:%d!\n",
1347 bug->function, bug->file, (unsigned int)bug->line);
1350 void excprint(struct pt_regs *fp)
1352 unsigned long trap;
1354 #ifdef CONFIG_SMP
1355 printf("cpu 0x%x: ", smp_processor_id());
1356 #endif /* CONFIG_SMP */
1358 trap = TRAP(fp);
1359 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1360 printf(" pc: ");
1361 xmon_print_symbol(fp->nip, ": ", "\n");
1363 printf(" lr: ", fp->link);
1364 xmon_print_symbol(fp->link, ": ", "\n");
1366 printf(" sp: %lx\n", fp->gpr[1]);
1367 printf(" msr: %lx\n", fp->msr);
1369 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1370 printf(" dar: %lx\n", fp->dar);
1371 if (trap != 0x380)
1372 printf(" dsisr: %lx\n", fp->dsisr);
1375 printf(" current = 0x%lx\n", current);
1376 #ifdef CONFIG_PPC64
1377 printf(" paca = 0x%lx\n", get_paca());
1378 #endif
1379 if (current) {
1380 printf(" pid = %ld, comm = %s\n",
1381 current->pid, current->comm);
1384 if (trap == 0x700)
1385 print_bug_trap(fp);
1388 void prregs(struct pt_regs *fp)
1390 int n, trap;
1391 unsigned long base;
1392 struct pt_regs regs;
1394 if (scanhex(&base)) {
1395 if (setjmp(bus_error_jmp) == 0) {
1396 catch_memory_errors = 1;
1397 sync();
1398 regs = *(struct pt_regs *)base;
1399 sync();
1400 __delay(200);
1401 } else {
1402 catch_memory_errors = 0;
1403 printf("*** Error reading registers from "REG"\n",
1404 base);
1405 return;
1407 catch_memory_errors = 0;
1408 fp = &regs;
1411 #ifdef CONFIG_PPC64
1412 if (FULL_REGS(fp)) {
1413 for (n = 0; n < 16; ++n)
1414 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1415 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1416 } else {
1417 for (n = 0; n < 7; ++n)
1418 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1419 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1421 #else
1422 for (n = 0; n < 32; ++n) {
1423 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1424 (n & 3) == 3? "\n": " ");
1425 if (n == 12 && !FULL_REGS(fp)) {
1426 printf("\n");
1427 break;
1430 #endif
1431 printf("pc = ");
1432 xmon_print_symbol(fp->nip, " ", "\n");
1433 printf("lr = ");
1434 xmon_print_symbol(fp->link, " ", "\n");
1435 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1436 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1437 fp->ctr, fp->xer, fp->trap);
1438 trap = TRAP(fp);
1439 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1440 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1443 void cacheflush(void)
1445 int cmd;
1446 unsigned long nflush;
1448 cmd = inchar();
1449 if (cmd != 'i')
1450 termch = cmd;
1451 scanhex((void *)&adrs);
1452 if (termch != '\n')
1453 termch = 0;
1454 nflush = 1;
1455 scanhex(&nflush);
1456 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1457 if (setjmp(bus_error_jmp) == 0) {
1458 catch_memory_errors = 1;
1459 sync();
1461 if (cmd != 'i') {
1462 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1463 cflush((void *) adrs);
1464 } else {
1465 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1466 cinval((void *) adrs);
1468 sync();
1469 /* wait a little while to see if we get a machine check */
1470 __delay(200);
1472 catch_memory_errors = 0;
1475 unsigned long
1476 read_spr(int n)
1478 unsigned int instrs[2];
1479 unsigned long (*code)(void);
1480 unsigned long ret = -1UL;
1481 #ifdef CONFIG_PPC64
1482 unsigned long opd[3];
1484 opd[0] = (unsigned long)instrs;
1485 opd[1] = 0;
1486 opd[2] = 0;
1487 code = (unsigned long (*)(void)) opd;
1488 #else
1489 code = (unsigned long (*)(void)) instrs;
1490 #endif
1492 /* mfspr r3,n; blr */
1493 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1494 instrs[1] = 0x4e800020;
1495 store_inst(instrs);
1496 store_inst(instrs+1);
1498 if (setjmp(bus_error_jmp) == 0) {
1499 catch_memory_errors = 1;
1500 sync();
1502 ret = code();
1504 sync();
1505 /* wait a little while to see if we get a machine check */
1506 __delay(200);
1507 n = size;
1510 return ret;
1513 void
1514 write_spr(int n, unsigned long val)
1516 unsigned int instrs[2];
1517 unsigned long (*code)(unsigned long);
1518 #ifdef CONFIG_PPC64
1519 unsigned long opd[3];
1521 opd[0] = (unsigned long)instrs;
1522 opd[1] = 0;
1523 opd[2] = 0;
1524 code = (unsigned long (*)(unsigned long)) opd;
1525 #else
1526 code = (unsigned long (*)(unsigned long)) instrs;
1527 #endif
1529 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1530 instrs[1] = 0x4e800020;
1531 store_inst(instrs);
1532 store_inst(instrs+1);
1534 if (setjmp(bus_error_jmp) == 0) {
1535 catch_memory_errors = 1;
1536 sync();
1538 code(val);
1540 sync();
1541 /* wait a little while to see if we get a machine check */
1542 __delay(200);
1543 n = size;
1547 static unsigned long regno;
1548 extern char exc_prolog;
1549 extern char dec_exc;
1551 void super_regs(void)
1553 int cmd;
1554 unsigned long val;
1555 #ifdef CONFIG_PPC_ISERIES
1556 struct paca_struct *ptrPaca = NULL;
1557 struct lppaca *ptrLpPaca = NULL;
1558 struct ItLpRegSave *ptrLpRegSave = NULL;
1559 #endif
1561 cmd = skipbl();
1562 if (cmd == '\n') {
1563 unsigned long sp, toc;
1564 asm("mr %0,1" : "=r" (sp) :);
1565 asm("mr %0,2" : "=r" (toc) :);
1567 printf("msr = "REG" sprg0= "REG"\n",
1568 mfmsr(), mfspr(SPRN_SPRG0));
1569 printf("pvr = "REG" sprg1= "REG"\n",
1570 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1571 printf("dec = "REG" sprg2= "REG"\n",
1572 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1573 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1574 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1575 #ifdef CONFIG_PPC_ISERIES
1576 // Dump out relevant Paca data areas.
1577 printf("Paca: \n");
1578 ptrPaca = get_paca();
1580 printf(" Local Processor Control Area (LpPaca): \n");
1581 ptrLpPaca = ptrPaca->lppaca_ptr;
1582 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1583 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1584 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1585 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1586 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1588 printf(" Local Processor Register Save Area (LpRegSave): \n");
1589 ptrLpRegSave = ptrPaca->reg_save_ptr;
1590 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1591 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1592 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1593 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1594 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1595 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1596 #endif
1598 return;
1601 scanhex(&regno);
1602 switch (cmd) {
1603 case 'w':
1604 val = read_spr(regno);
1605 scanhex(&val);
1606 write_spr(regno, val);
1607 /* fall through */
1608 case 'r':
1609 printf("spr %lx = %lx\n", regno, read_spr(regno));
1610 break;
1612 scannl();
1616 * Stuff for reading and writing memory safely
1619 mread(unsigned long adrs, void *buf, int size)
1621 volatile int n;
1622 char *p, *q;
1624 n = 0;
1625 if (setjmp(bus_error_jmp) == 0) {
1626 catch_memory_errors = 1;
1627 sync();
1628 p = (char *)adrs;
1629 q = (char *)buf;
1630 switch (size) {
1631 case 2:
1632 *(u16 *)q = *(u16 *)p;
1633 break;
1634 case 4:
1635 *(u32 *)q = *(u32 *)p;
1636 break;
1637 case 8:
1638 *(u64 *)q = *(u64 *)p;
1639 break;
1640 default:
1641 for( ; n < size; ++n) {
1642 *q++ = *p++;
1643 sync();
1646 sync();
1647 /* wait a little while to see if we get a machine check */
1648 __delay(200);
1649 n = size;
1651 catch_memory_errors = 0;
1652 return n;
1656 mwrite(unsigned long adrs, void *buf, int size)
1658 volatile int n;
1659 char *p, *q;
1661 n = 0;
1662 if (setjmp(bus_error_jmp) == 0) {
1663 catch_memory_errors = 1;
1664 sync();
1665 p = (char *) adrs;
1666 q = (char *) buf;
1667 switch (size) {
1668 case 2:
1669 *(u16 *)p = *(u16 *)q;
1670 break;
1671 case 4:
1672 *(u32 *)p = *(u32 *)q;
1673 break;
1674 case 8:
1675 *(u64 *)p = *(u64 *)q;
1676 break;
1677 default:
1678 for ( ; n < size; ++n) {
1679 *p++ = *q++;
1680 sync();
1683 sync();
1684 /* wait a little while to see if we get a machine check */
1685 __delay(200);
1686 n = size;
1687 } else {
1688 printf("*** Error writing address %x\n", adrs + n);
1690 catch_memory_errors = 0;
1691 return n;
1694 static int fault_type;
1695 static int fault_except;
1696 static char *fault_chars[] = { "--", "**", "##" };
1698 static int handle_fault(struct pt_regs *regs)
1700 fault_except = TRAP(regs);
1701 switch (TRAP(regs)) {
1702 case 0x200:
1703 fault_type = 0;
1704 break;
1705 case 0x300:
1706 case 0x380:
1707 fault_type = 1;
1708 break;
1709 default:
1710 fault_type = 2;
1713 longjmp(bus_error_jmp, 1);
1715 return 0;
1718 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1720 void
1721 byterev(unsigned char *val, int size)
1723 int t;
1725 switch (size) {
1726 case 2:
1727 SWAP(val[0], val[1], t);
1728 break;
1729 case 4:
1730 SWAP(val[0], val[3], t);
1731 SWAP(val[1], val[2], t);
1732 break;
1733 case 8: /* is there really any use for this? */
1734 SWAP(val[0], val[7], t);
1735 SWAP(val[1], val[6], t);
1736 SWAP(val[2], val[5], t);
1737 SWAP(val[3], val[4], t);
1738 break;
1742 static int brev;
1743 static int mnoread;
1745 static char *memex_help_string =
1746 "Memory examine command usage:\n"
1747 "m [addr] [flags] examine/change memory\n"
1748 " addr is optional. will start where left off.\n"
1749 " flags may include chars from this set:\n"
1750 " b modify by bytes (default)\n"
1751 " w modify by words (2 byte)\n"
1752 " l modify by longs (4 byte)\n"
1753 " d modify by doubleword (8 byte)\n"
1754 " r toggle reverse byte order mode\n"
1755 " n do not read memory (for i/o spaces)\n"
1756 " . ok to read (default)\n"
1757 "NOTE: flags are saved as defaults\n"
1760 static char *memex_subcmd_help_string =
1761 "Memory examine subcommands:\n"
1762 " hexval write this val to current location\n"
1763 " 'string' write chars from string to this location\n"
1764 " ' increment address\n"
1765 " ^ decrement address\n"
1766 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1767 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1768 " ` clear no-read flag\n"
1769 " ; stay at this addr\n"
1770 " v change to byte mode\n"
1771 " w change to word (2 byte) mode\n"
1772 " l change to long (4 byte) mode\n"
1773 " u change to doubleword (8 byte) mode\n"
1774 " m addr change current addr\n"
1775 " n toggle no-read flag\n"
1776 " r toggle byte reverse flag\n"
1777 " < count back up count bytes\n"
1778 " > count skip forward count bytes\n"
1779 " x exit this mode\n"
1782 void
1783 memex(void)
1785 int cmd, inc, i, nslash;
1786 unsigned long n;
1787 unsigned char val[16];
1789 scanhex((void *)&adrs);
1790 cmd = skipbl();
1791 if (cmd == '?') {
1792 printf(memex_help_string);
1793 return;
1794 } else {
1795 termch = cmd;
1797 last_cmd = "m\n";
1798 while ((cmd = skipbl()) != '\n') {
1799 switch( cmd ){
1800 case 'b': size = 1; break;
1801 case 'w': size = 2; break;
1802 case 'l': size = 4; break;
1803 case 'd': size = 8; break;
1804 case 'r': brev = !brev; break;
1805 case 'n': mnoread = 1; break;
1806 case '.': mnoread = 0; break;
1809 if( size <= 0 )
1810 size = 1;
1811 else if( size > 8 )
1812 size = 8;
1813 for(;;){
1814 if (!mnoread)
1815 n = mread(adrs, val, size);
1816 printf(REG"%c", adrs, brev? 'r': ' ');
1817 if (!mnoread) {
1818 if (brev)
1819 byterev(val, size);
1820 putchar(' ');
1821 for (i = 0; i < n; ++i)
1822 printf("%.2x", val[i]);
1823 for (; i < size; ++i)
1824 printf("%s", fault_chars[fault_type]);
1826 putchar(' ');
1827 inc = size;
1828 nslash = 0;
1829 for(;;){
1830 if( scanhex(&n) ){
1831 for (i = 0; i < size; ++i)
1832 val[i] = n >> (i * 8);
1833 if (!brev)
1834 byterev(val, size);
1835 mwrite(adrs, val, size);
1836 inc = size;
1838 cmd = skipbl();
1839 if (cmd == '\n')
1840 break;
1841 inc = 0;
1842 switch (cmd) {
1843 case '\'':
1844 for(;;){
1845 n = inchar();
1846 if( n == '\\' )
1847 n = bsesc();
1848 else if( n == '\'' )
1849 break;
1850 for (i = 0; i < size; ++i)
1851 val[i] = n >> (i * 8);
1852 if (!brev)
1853 byterev(val, size);
1854 mwrite(adrs, val, size);
1855 adrs += size;
1857 adrs -= size;
1858 inc = size;
1859 break;
1860 case ',':
1861 adrs += size;
1862 break;
1863 case '.':
1864 mnoread = 0;
1865 break;
1866 case ';':
1867 break;
1868 case 'x':
1869 case EOF:
1870 scannl();
1871 return;
1872 case 'b':
1873 case 'v':
1874 size = 1;
1875 break;
1876 case 'w':
1877 size = 2;
1878 break;
1879 case 'l':
1880 size = 4;
1881 break;
1882 case 'u':
1883 size = 8;
1884 break;
1885 case '^':
1886 adrs -= size;
1887 break;
1888 break;
1889 case '/':
1890 if (nslash > 0)
1891 adrs -= 1 << nslash;
1892 else
1893 nslash = 0;
1894 nslash += 4;
1895 adrs += 1 << nslash;
1896 break;
1897 case '\\':
1898 if (nslash < 0)
1899 adrs += 1 << -nslash;
1900 else
1901 nslash = 0;
1902 nslash -= 4;
1903 adrs -= 1 << -nslash;
1904 break;
1905 case 'm':
1906 scanhex((void *)&adrs);
1907 break;
1908 case 'n':
1909 mnoread = 1;
1910 break;
1911 case 'r':
1912 brev = !brev;
1913 break;
1914 case '<':
1915 n = size;
1916 scanhex(&n);
1917 adrs -= n;
1918 break;
1919 case '>':
1920 n = size;
1921 scanhex(&n);
1922 adrs += n;
1923 break;
1924 case '?':
1925 printf(memex_subcmd_help_string);
1926 break;
1929 adrs += inc;
1934 bsesc(void)
1936 int c;
1938 c = inchar();
1939 switch( c ){
1940 case 'n': c = '\n'; break;
1941 case 'r': c = '\r'; break;
1942 case 'b': c = '\b'; break;
1943 case 't': c = '\t'; break;
1945 return c;
1948 static void xmon_rawdump (unsigned long adrs, long ndump)
1950 long n, m, r, nr;
1951 unsigned char temp[16];
1953 for (n = ndump; n > 0;) {
1954 r = n < 16? n: 16;
1955 nr = mread(adrs, temp, r);
1956 adrs += nr;
1957 for (m = 0; m < r; ++m) {
1958 if (m < nr)
1959 printf("%.2x", temp[m]);
1960 else
1961 printf("%s", fault_chars[fault_type]);
1963 n -= r;
1964 if (nr < r)
1965 break;
1967 printf("\n");
1970 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1971 || ('a' <= (c) && (c) <= 'f') \
1972 || ('A' <= (c) && (c) <= 'F'))
1973 void
1974 dump(void)
1976 int c;
1978 c = inchar();
1979 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1980 termch = c;
1981 scanhex((void *)&adrs);
1982 if (termch != '\n')
1983 termch = 0;
1984 if (c == 'i') {
1985 scanhex(&nidump);
1986 if (nidump == 0)
1987 nidump = 16;
1988 else if (nidump > MAX_DUMP)
1989 nidump = MAX_DUMP;
1990 adrs += ppc_inst_dump(adrs, nidump, 1);
1991 last_cmd = "di\n";
1992 } else if (c == 'r') {
1993 scanhex(&ndump);
1994 if (ndump == 0)
1995 ndump = 64;
1996 xmon_rawdump(adrs, ndump);
1997 adrs += ndump;
1998 last_cmd = "dr\n";
1999 } else {
2000 scanhex(&ndump);
2001 if (ndump == 0)
2002 ndump = 64;
2003 else if (ndump > MAX_DUMP)
2004 ndump = MAX_DUMP;
2005 prdump(adrs, ndump);
2006 adrs += ndump;
2007 last_cmd = "d\n";
2011 void
2012 prdump(unsigned long adrs, long ndump)
2014 long n, m, c, r, nr;
2015 unsigned char temp[16];
2017 for (n = ndump; n > 0;) {
2018 printf(REG, adrs);
2019 putchar(' ');
2020 r = n < 16? n: 16;
2021 nr = mread(adrs, temp, r);
2022 adrs += nr;
2023 for (m = 0; m < r; ++m) {
2024 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2025 putchar(' ');
2026 if (m < nr)
2027 printf("%.2x", temp[m]);
2028 else
2029 printf("%s", fault_chars[fault_type]);
2031 for (; m < 16; ++m) {
2032 if ((m & (sizeof(long) - 1)) == 0)
2033 putchar(' ');
2034 printf(" ");
2036 printf(" |");
2037 for (m = 0; m < r; ++m) {
2038 if (m < nr) {
2039 c = temp[m];
2040 putchar(' ' <= c && c <= '~'? c: '.');
2041 } else
2042 putchar(' ');
2044 n -= r;
2045 for (; m < 16; ++m)
2046 putchar(' ');
2047 printf("|\n");
2048 if (nr < r)
2049 break;
2054 ppc_inst_dump(unsigned long adr, long count, int praddr)
2056 int nr, dotted;
2057 unsigned long first_adr;
2058 unsigned long inst, last_inst = 0;
2059 unsigned char val[4];
2061 dotted = 0;
2062 for (first_adr = adr; count > 0; --count, adr += 4) {
2063 nr = mread(adr, val, 4);
2064 if (nr == 0) {
2065 if (praddr) {
2066 const char *x = fault_chars[fault_type];
2067 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2069 break;
2071 inst = GETWORD(val);
2072 if (adr > first_adr && inst == last_inst) {
2073 if (!dotted) {
2074 printf(" ...\n");
2075 dotted = 1;
2077 continue;
2079 dotted = 0;
2080 last_inst = inst;
2081 if (praddr)
2082 printf(REG" %.8x", adr, inst);
2083 printf("\t");
2084 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2085 printf("\n");
2087 return adr - first_adr;
2090 void
2091 print_address(unsigned long addr)
2093 xmon_print_symbol(addr, "\t# ", "");
2098 * Memory operations - move, set, print differences
2100 static unsigned long mdest; /* destination address */
2101 static unsigned long msrc; /* source address */
2102 static unsigned long mval; /* byte value to set memory to */
2103 static unsigned long mcount; /* # bytes to affect */
2104 static unsigned long mdiffs; /* max # differences to print */
2106 void
2107 memops(int cmd)
2109 scanhex((void *)&mdest);
2110 if( termch != '\n' )
2111 termch = 0;
2112 scanhex((void *)(cmd == 's'? &mval: &msrc));
2113 if( termch != '\n' )
2114 termch = 0;
2115 scanhex((void *)&mcount);
2116 switch( cmd ){
2117 case 'm':
2118 memmove((void *)mdest, (void *)msrc, mcount);
2119 break;
2120 case 's':
2121 memset((void *)mdest, mval, mcount);
2122 break;
2123 case 'd':
2124 if( termch != '\n' )
2125 termch = 0;
2126 scanhex((void *)&mdiffs);
2127 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2128 break;
2132 void
2133 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2135 unsigned n, prt;
2137 prt = 0;
2138 for( n = nb; n > 0; --n )
2139 if( *p1++ != *p2++ )
2140 if( ++prt <= maxpr )
2141 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2142 p1[-1], p2 - 1, p2[-1]);
2143 if( prt > maxpr )
2144 printf("Total of %d differences\n", prt);
2147 static unsigned mend;
2148 static unsigned mask;
2150 void
2151 memlocate(void)
2153 unsigned a, n;
2154 unsigned char val[4];
2156 last_cmd = "ml";
2157 scanhex((void *)&mdest);
2158 if (termch != '\n') {
2159 termch = 0;
2160 scanhex((void *)&mend);
2161 if (termch != '\n') {
2162 termch = 0;
2163 scanhex((void *)&mval);
2164 mask = ~0;
2165 if (termch != '\n') termch = 0;
2166 scanhex((void *)&mask);
2169 n = 0;
2170 for (a = mdest; a < mend; a += 4) {
2171 if (mread(a, val, 4) == 4
2172 && ((GETWORD(val) ^ mval) & mask) == 0) {
2173 printf("%.16x: %.16x\n", a, GETWORD(val));
2174 if (++n >= 10)
2175 break;
2180 static unsigned long mskip = 0x1000;
2181 static unsigned long mlim = 0xffffffff;
2183 void
2184 memzcan(void)
2186 unsigned char v;
2187 unsigned a;
2188 int ok, ook;
2190 scanhex(&mdest);
2191 if (termch != '\n') termch = 0;
2192 scanhex(&mskip);
2193 if (termch != '\n') termch = 0;
2194 scanhex(&mlim);
2195 ook = 0;
2196 for (a = mdest; a < mlim; a += mskip) {
2197 ok = mread(a, &v, 1);
2198 if (ok && !ook) {
2199 printf("%.8x .. ", a);
2200 } else if (!ok && ook)
2201 printf("%.8x\n", a - mskip);
2202 ook = ok;
2203 if (a + mskip < a)
2204 break;
2206 if (ook)
2207 printf("%.8x\n", a - mskip);
2210 void proccall(void)
2212 unsigned long args[8];
2213 unsigned long ret;
2214 int i;
2215 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2216 unsigned long, unsigned long, unsigned long,
2217 unsigned long, unsigned long, unsigned long);
2218 callfunc_t func;
2220 if (!scanhex(&adrs))
2221 return;
2222 if (termch != '\n')
2223 termch = 0;
2224 for (i = 0; i < 8; ++i)
2225 args[i] = 0;
2226 for (i = 0; i < 8; ++i) {
2227 if (!scanhex(&args[i]) || termch == '\n')
2228 break;
2229 termch = 0;
2231 func = (callfunc_t) adrs;
2232 ret = 0;
2233 if (setjmp(bus_error_jmp) == 0) {
2234 catch_memory_errors = 1;
2235 sync();
2236 ret = func(args[0], args[1], args[2], args[3],
2237 args[4], args[5], args[6], args[7]);
2238 sync();
2239 printf("return value is %x\n", ret);
2240 } else {
2241 printf("*** %x exception occurred\n", fault_except);
2243 catch_memory_errors = 0;
2246 /* Input scanning routines */
2248 skipbl(void)
2250 int c;
2252 if( termch != 0 ){
2253 c = termch;
2254 termch = 0;
2255 } else
2256 c = inchar();
2257 while( c == ' ' || c == '\t' )
2258 c = inchar();
2259 return c;
2262 #define N_PTREGS 44
2263 static char *regnames[N_PTREGS] = {
2264 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2265 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2266 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2267 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2268 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2269 #ifdef CONFIG_PPC64
2270 "softe",
2271 #else
2272 "mq",
2273 #endif
2274 "trap", "dar", "dsisr", "res"
2278 scanhex(unsigned long *vp)
2280 int c, d;
2281 unsigned long v;
2283 c = skipbl();
2284 if (c == '%') {
2285 /* parse register name */
2286 char regname[8];
2287 int i;
2289 for (i = 0; i < sizeof(regname) - 1; ++i) {
2290 c = inchar();
2291 if (!isalnum(c)) {
2292 termch = c;
2293 break;
2295 regname[i] = c;
2297 regname[i] = 0;
2298 for (i = 0; i < N_PTREGS; ++i) {
2299 if (strcmp(regnames[i], regname) == 0) {
2300 if (xmon_regs == NULL) {
2301 printf("regs not available\n");
2302 return 0;
2304 *vp = ((unsigned long *)xmon_regs)[i];
2305 return 1;
2308 printf("invalid register name '%%%s'\n", regname);
2309 return 0;
2312 /* skip leading "0x" if any */
2314 if (c == '0') {
2315 c = inchar();
2316 if (c == 'x') {
2317 c = inchar();
2318 } else {
2319 d = hexdigit(c);
2320 if (d == EOF) {
2321 termch = c;
2322 *vp = 0;
2323 return 1;
2326 } else if (c == '$') {
2327 int i;
2328 for (i=0; i<63; i++) {
2329 c = inchar();
2330 if (isspace(c)) {
2331 termch = c;
2332 break;
2334 tmpstr[i] = c;
2336 tmpstr[i++] = 0;
2337 *vp = 0;
2338 if (setjmp(bus_error_jmp) == 0) {
2339 catch_memory_errors = 1;
2340 sync();
2341 *vp = kallsyms_lookup_name(tmpstr);
2342 sync();
2344 catch_memory_errors = 0;
2345 if (!(*vp)) {
2346 printf("unknown symbol '%s'\n", tmpstr);
2347 return 0;
2349 return 1;
2352 d = hexdigit(c);
2353 if (d == EOF) {
2354 termch = c;
2355 return 0;
2357 v = 0;
2358 do {
2359 v = (v << 4) + d;
2360 c = inchar();
2361 d = hexdigit(c);
2362 } while (d != EOF);
2363 termch = c;
2364 *vp = v;
2365 return 1;
2368 void
2369 scannl(void)
2371 int c;
2373 c = termch;
2374 termch = 0;
2375 while( c != '\n' )
2376 c = inchar();
2379 int hexdigit(int c)
2381 if( '0' <= c && c <= '9' )
2382 return c - '0';
2383 if( 'A' <= c && c <= 'F' )
2384 return c - ('A' - 10);
2385 if( 'a' <= c && c <= 'f' )
2386 return c - ('a' - 10);
2387 return EOF;
2390 void
2391 getstring(char *s, int size)
2393 int c;
2395 c = skipbl();
2396 do {
2397 if( size > 1 ){
2398 *s++ = c;
2399 --size;
2401 c = inchar();
2402 } while( c != ' ' && c != '\t' && c != '\n' );
2403 termch = c;
2404 *s = 0;
2407 static char line[256];
2408 static char *lineptr;
2410 void
2411 flush_input(void)
2413 lineptr = NULL;
2417 inchar(void)
2419 if (lineptr == NULL || *lineptr == 0) {
2420 if (xmon_gets(line, sizeof(line)) == NULL) {
2421 lineptr = NULL;
2422 return EOF;
2424 lineptr = line;
2426 return *lineptr++;
2429 void
2430 take_input(char *str)
2432 lineptr = str;
2436 static void
2437 symbol_lookup(void)
2439 int type = inchar();
2440 unsigned long addr;
2441 static char tmp[64];
2443 switch (type) {
2444 case 'a':
2445 if (scanhex(&addr))
2446 xmon_print_symbol(addr, ": ", "\n");
2447 termch = 0;
2448 break;
2449 case 's':
2450 getstring(tmp, 64);
2451 if (setjmp(bus_error_jmp) == 0) {
2452 catch_memory_errors = 1;
2453 sync();
2454 addr = kallsyms_lookup_name(tmp);
2455 if (addr)
2456 printf("%s: %lx\n", tmp, addr);
2457 else
2458 printf("Symbol '%s' not found.\n", tmp);
2459 sync();
2461 catch_memory_errors = 0;
2462 termch = 0;
2463 break;
2468 /* Print an address in numeric and symbolic form (if possible) */
2469 static void xmon_print_symbol(unsigned long address, const char *mid,
2470 const char *after)
2472 char *modname;
2473 const char *name = NULL;
2474 unsigned long offset, size;
2476 printf(REG, address);
2477 if (setjmp(bus_error_jmp) == 0) {
2478 catch_memory_errors = 1;
2479 sync();
2480 name = kallsyms_lookup(address, &size, &offset, &modname,
2481 tmpstr);
2482 sync();
2483 /* wait a little while to see if we get a machine check */
2484 __delay(200);
2487 catch_memory_errors = 0;
2489 if (name) {
2490 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2491 if (modname)
2492 printf(" [%s]", modname);
2494 printf("%s", after);
2497 #ifdef CONFIG_PPC64
2498 static void dump_slb(void)
2500 int i;
2501 unsigned long tmp;
2503 printf("SLB contents of cpu %x\n", smp_processor_id());
2505 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2506 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2507 printf("%02d %016lx ", i, tmp);
2509 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2510 printf("%016lx\n", tmp);
2514 static void dump_stab(void)
2516 int i;
2517 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2519 printf("Segment table contents of cpu %x\n", smp_processor_id());
2521 for (i = 0; i < PAGE_SIZE/16; i++) {
2522 unsigned long a, b;
2524 a = *tmp++;
2525 b = *tmp++;
2527 if (a || b) {
2528 printf("%03d %016lx ", i, a);
2529 printf("%016lx\n", b);
2534 void dump_segments(void)
2536 if (cpu_has_feature(CPU_FTR_SLB))
2537 dump_slb();
2538 else
2539 dump_stab();
2541 #endif
2543 #ifdef CONFIG_PPC_STD_MMU_32
2544 void dump_segments(void)
2546 int i;
2548 printf("sr0-15 =");
2549 for (i = 0; i < 16; ++i)
2550 printf(" %x", mfsrin(i));
2551 printf("\n");
2553 #endif
2555 void xmon_init(int enable)
2557 if (enable) {
2558 __debugger = xmon;
2559 __debugger_ipi = xmon_ipi;
2560 __debugger_bpt = xmon_bpt;
2561 __debugger_sstep = xmon_sstep;
2562 __debugger_iabr_match = xmon_iabr_match;
2563 __debugger_dabr_match = xmon_dabr_match;
2564 __debugger_fault_handler = xmon_fault_handler;
2565 } else {
2566 __debugger = NULL;
2567 __debugger_ipi = NULL;
2568 __debugger_bpt = NULL;
2569 __debugger_sstep = NULL;
2570 __debugger_iabr_match = NULL;
2571 __debugger_dabr_match = NULL;
2572 __debugger_fault_handler = NULL;
2574 xmon_map_scc();
2577 #ifdef CONFIG_MAGIC_SYSRQ
2578 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2579 struct tty_struct *tty)
2581 /* ensure xmon is enabled */
2582 xmon_init(1);
2583 debugger(pt_regs);
2586 static struct sysrq_key_op sysrq_xmon_op =
2588 .handler = sysrq_handle_xmon,
2589 .help_msg = "Xmon",
2590 .action_msg = "Entering xmon",
2593 static int __init setup_xmon_sysrq(void)
2595 register_sysrq_key('x', &sysrq_xmon_op);
2596 return 0;
2598 __initcall(setup_xmon_sysrq);
2599 #endif /* CONFIG_MAGIC_SYSRQ */