2 * Routines providing a simple monitor for use on the PowerMac.
4 * Copyright (C) 1996 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/config.h>
12 #include <linux/errno.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
16 #include <linux/reboot.h>
17 #include <linux/delay.h>
18 #include <linux/kallsyms.h>
19 #include <linux/cpumask.h>
21 #include <asm/ptrace.h>
22 #include <asm/string.h>
24 #include <asm/machdep.h>
25 #include <asm/processor.h>
26 #include <asm/pgtable.h>
28 #include <asm/mmu_context.h>
31 #include <asm/ppcdebug.h>
32 #include <asm/cputable.h>
38 #define scanhex xmon_scanhex
39 #define skipbl xmon_skipbl
42 volatile cpumask_t cpus_in_xmon = CPU_MASK_NONE;
43 static unsigned long xmon_taken = 1;
44 static int xmon_owner;
46 #endif /* CONFIG_SMP */
48 static unsigned long in_xmon = 0;
50 static unsigned long adrs;
52 static unsigned long ndump = 64;
53 static unsigned long nidump = 16;
54 static unsigned long ncsum = 4096;
56 static char tmpstr[128];
58 #define JMP_BUF_LEN (184/sizeof(long))
59 static long bus_error_jmp[JMP_BUF_LEN];
60 static int catch_memory_errors;
61 static long *xmon_fault_jmp[NR_CPUS];
62 #define setjmp xmon_setjmp
63 #define longjmp xmon_longjmp
65 /* Breakpoint stuff */
67 unsigned long address;
68 unsigned int instr[2];
74 /* Bits in bpt.enabled */
75 #define BP_IABR_TE 1 /* IABR translation enabled */
81 static struct bpt bpts[NBPTS];
82 static struct bpt dabr;
83 static struct bpt *iabr;
84 static unsigned bpinstr = 0x7fe00008; /* trap */
86 #define BP_NUM(bp) ((bp) - bpts + 1)
88 /* Bits in SRR1 that are copied from MSR */
89 #define MSR_MASK 0xffffffff87c0ffff
92 static int cmds(struct pt_regs *);
93 static int mread(unsigned long, void *, int);
94 static int mwrite(unsigned long, void *, int);
95 static int handle_fault(struct pt_regs *);
96 static void byterev(unsigned char *, int);
97 static void memex(void);
98 static int bsesc(void);
99 static void dump(void);
100 static void prdump(unsigned long, long);
101 static int ppc_inst_dump(unsigned long, long, int);
102 void print_address(unsigned long);
103 static void backtrace(struct pt_regs *);
104 static void excprint(struct pt_regs *);
105 static void prregs(struct pt_regs *);
106 static void memops(int);
107 static void memlocate(void);
108 static void memzcan(void);
109 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
111 int scanhex(unsigned long *valp);
112 static void scannl(void);
113 static int hexdigit(int);
114 void getstring(char *, int);
115 static void flush_input(void);
116 static int inchar(void);
117 static void take_input(char *);
118 static unsigned long read_spr(int);
119 static void write_spr(int, unsigned long);
120 static void super_regs(void);
121 static void remove_bpts(void);
122 static void insert_bpts(void);
123 static void remove_cpu_bpts(void);
124 static void insert_cpu_bpts(void);
125 static struct bpt *at_breakpoint(unsigned long pc);
126 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
127 static int do_step(struct pt_regs *);
128 static void bpt_cmds(void);
129 static void cacheflush(void);
130 static int cpu_cmd(void);
131 static void csum(void);
132 static void bootcmds(void);
133 void dump_segments(void);
134 static void symbol_lookup(void);
135 static int emulate_step(struct pt_regs *regs, unsigned int instr);
136 static void xmon_print_symbol(unsigned long address, const char *mid,
138 static const char *getvecname(unsigned long vec);
140 static void debug_trace(void);
142 extern int print_insn_powerpc(unsigned long, unsigned long, int);
143 extern void printf(const char *fmt, ...);
144 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
145 extern int xmon_putc(int c, void *f);
146 extern int putchar(int ch);
147 extern int xmon_read_poll(void);
148 extern int setjmp(long *);
149 extern void longjmp(long *, int);
150 extern unsigned long _ASR;
151 extern char SystemCall_common[];
153 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
155 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
157 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
158 || ('a' <= (c) && (c) <= 'f') \
159 || ('A' <= (c) && (c) <= 'F'))
160 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
161 || ('a' <= (c) && (c) <= 'z') \
162 || ('A' <= (c) && (c) <= 'Z'))
163 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
165 static char *help_string = "\
167 b show breakpoints\n\
168 bd set data breakpoint\n\
169 bi set instruction breakpoint\n\
170 bc clear breakpoint\n"
173 c print cpus stopped in xmon\n\
174 c# try to switch to cpu number h (in hex)\n"
179 di dump instructions\n\
180 df dump float values\n\
181 dd dump double values\n\
182 e print exception information\n\
184 la lookup symbol+offset of specified address\n\
185 ls lookup address of specified symbol\n\
186 m examine/change memory\n\
187 mm move a block of memory\n\
188 ms set a block of memory\n\
189 md compare two blocks of memory\n\
190 ml locate a block of memory\n\
191 mz zero a block of memory\n\
192 mi show information about memory allocation\n\
193 p show the task list\n\
196 S print special registers\n\
198 T Enable/Disable PPCDBG flags\n\
199 x exit monitor and recover\n\
200 X exit monitor and dont recover\n\
201 u dump segment table or SLB\n\
208 static struct pt_regs *xmon_regs;
210 extern inline void sync(void)
212 asm volatile("sync; isync");
215 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
216 A PPC stack frame looks like this:
223 Parameter save area (SP+48)
224 TOC save area (SP+40)
225 link editor doubleword (SP+32)
226 compiler doubleword (SP+24)
231 Note that the LR (ret addr) may not be saved in the current frame if
232 no functions have been called from the current function.
236 * We don't allow single-stepping an mtmsrd that would clear
237 * MSR_RI, since that would make the exception unrecoverable.
238 * Since we need to single-step to proceed from a breakpoint,
239 * we don't allow putting a breakpoint on an mtmsrd instruction.
240 * Similarly we don't allow breakpoints on rfid instructions.
241 * These macros tell us if an instruction is a mtmsrd or rfid.
243 #define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
244 #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
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 #ifndef CONFIG_PPC_ISERIES
256 /* Since this can't be a module, args should end up below 4GB. */
257 static struct rtas_args args;
259 if (systemcfg->platform & PLATFORM_PSERIES) {
261 * At this point we have got all the cpus we can into
262 * xmon, so there is hopefully no other cpu calling RTAS
263 * at the moment, even though we don't take rtas.lock.
264 * If we did try to take rtas.lock there would be a
265 * real possibility of deadlock.
267 args.token = rtas_token("set-indicator");
268 if (args.token == RTAS_UNKNOWN_SERVICE)
272 args.rets = &args.args[3];
273 args.args[0] = SURVEILLANCE_TOKEN;
276 enter_rtas(__pa(&args));
282 static int xmon_speaker;
284 static void get_output_lock(void)
286 int me = smp_processor_id() + 0x100;
287 int last_speaker = 0, prev;
290 if (xmon_speaker == me)
293 if (xmon_speaker == 0) {
294 last_speaker = cmpxchg(&xmon_speaker, 0, me);
295 if (last_speaker == 0)
299 while (xmon_speaker == last_speaker) {
302 /* hostile takeover */
303 prev = cmpxchg(&xmon_speaker, last_speaker, me);
304 if (prev == last_speaker)
311 static void release_output_lock(void)
317 int xmon_core(struct pt_regs *regs, int fromipi)
322 long recurse_jmp[JMP_BUF_LEN];
323 unsigned long offset;
327 unsigned long timeout;
331 set_msrd(msr & ~MSR_EE); /* disable interrupts */
333 bp = in_breakpoint_table(regs->nip, &offset);
335 regs->nip = bp->address + offset;
336 atomic_dec(&bp->ref_count);
342 cpu = smp_processor_id();
343 if (cpu_isset(cpu, cpus_in_xmon)) {
346 printf("cpu 0x%x: Exception %lx %s in xmon, "
347 "returning to main loop\n",
348 cpu, regs->trap, getvecname(TRAP(regs)));
349 longjmp(xmon_fault_jmp[cpu], 1);
352 if (setjmp(recurse_jmp) != 0) {
353 if (!in_xmon || !xmon_gate) {
354 printf("xmon: WARNING: bad recursive fault "
355 "on cpu 0x%x\n", cpu);
358 secondary = !(xmon_taken && cpu == xmon_owner);
362 xmon_fault_jmp[cpu] = recurse_jmp;
363 cpu_set(cpu, cpus_in_xmon);
366 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
367 bp = at_breakpoint(regs->nip);
368 if (bp || (regs->msr & MSR_RI) == 0)
375 printf("cpu 0x%x stopped at breakpoint 0x%x (",
377 xmon_print_symbol(regs->nip, " ", ")\n");
379 if ((regs->msr & MSR_RI) == 0)
380 printf("WARNING: exception is not recoverable, "
382 release_output_lock();
387 while (secondary && !xmon_gate) {
391 secondary = test_and_set_bit(0, &in_xmon);
396 if (!secondary && !xmon_gate) {
397 /* we are the first cpu to come in */
398 /* interrupt other cpu(s) */
399 int ncpus = num_online_cpus();
404 smp_send_debugger_break(MSG_ALL_BUT_SELF);
405 /* wait for other cpus to come in */
406 for (timeout = 100000000; timeout != 0; --timeout)
407 if (cpus_weight(cpus_in_xmon) >= ncpus)
411 disable_surveillance();
412 /* for breakpoint or single step, print the current instr. */
413 if (bp || TRAP(regs) == 0xd00)
414 ppc_inst_dump(regs->nip, 1, 0);
415 printf("enter ? for help\n");
424 if (cpu == xmon_owner) {
425 if (!test_and_set_bit(0, &xmon_taken)) {
430 while (cpu == xmon_owner)
444 /* have switched to some other cpu */
449 cpu_clear(cpu, cpus_in_xmon);
450 xmon_fault_jmp[cpu] = NULL;
453 /* UP is simple... */
455 printf("Exception %lx %s in xmon, returning to main loop\n",
456 regs->trap, getvecname(TRAP(regs)));
457 longjmp(xmon_fault_jmp[0], 1);
459 if (setjmp(recurse_jmp) == 0) {
460 xmon_fault_jmp[0] = recurse_jmp;
464 bp = at_breakpoint(regs->nip);
466 printf("Stopped at breakpoint %x (", BP_NUM(bp));
467 xmon_print_symbol(regs->nip, " ", ")\n");
469 if ((regs->msr & MSR_RI) == 0)
470 printf("WARNING: exception is not recoverable, "
473 disable_surveillance();
474 /* for breakpoint or single step, print the current instr. */
475 if (bp || TRAP(regs) == 0xd00)
476 ppc_inst_dump(regs->nip, 1, 0);
477 printf("enter ? for help\n");
486 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
487 bp = at_breakpoint(regs->nip);
489 int stepped = emulate_step(regs, bp->instr[0]);
491 regs->nip = (unsigned long) &bp->instr[0];
492 atomic_inc(&bp->ref_count);
499 set_msrd(msr); /* restore interrupt enable */
504 int xmon(struct pt_regs *excp)
509 /* Ok, grab regs as they are now.
510 This won't do a particularily good job because the
511 prologue has already been executed.
512 ToDo: We could reach back into the callers save
513 area to do a better job of representing the
516 asm volatile ("std 0,0(%0)\n\
547 std 31,248(%0)" : : "b" (®s));
549 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
550 regs.msr = get_msr();
551 regs.ctr = get_ctr();
552 regs.xer = get_xer();
557 return xmon_core(excp, 0);
560 int xmon_bpt(struct pt_regs *regs)
563 unsigned long offset;
565 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
568 /* Are we at the trap at bp->instr[1] for some bp? */
569 bp = in_breakpoint_table(regs->nip, &offset);
570 if (bp != NULL && offset == 4) {
571 regs->nip = bp->address + 4;
572 atomic_dec(&bp->ref_count);
576 /* Are we at a breakpoint? */
577 bp = at_breakpoint(regs->nip);
586 int xmon_sstep(struct pt_regs *regs)
594 int xmon_dabr_match(struct pt_regs *regs)
596 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
602 int xmon_iabr_match(struct pt_regs *regs)
604 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
612 int xmon_ipi(struct pt_regs *regs)
615 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
621 int xmon_fault_handler(struct pt_regs *regs)
624 unsigned long offset;
626 if (in_xmon && catch_memory_errors)
627 handle_fault(regs); /* doesn't return */
629 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
630 bp = in_breakpoint_table(regs->nip, &offset);
632 regs->nip = bp->address + offset;
633 atomic_dec(&bp->ref_count);
641 static struct bpt *at_breakpoint(unsigned long pc)
647 for (i = 0; i < NBPTS; ++i, ++bp)
648 if (bp->enabled && pc == bp->address)
653 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
657 off = nip - (unsigned long) bpts;
658 if (off >= sizeof(bpts))
660 off %= sizeof(struct bpt);
661 if (off != offsetof(struct bpt, instr[0])
662 && off != offsetof(struct bpt, instr[1]))
664 *offp = off - offsetof(struct bpt, instr[0]);
665 return (struct bpt *) (nip - off);
668 static struct bpt *new_breakpoint(unsigned long a)
673 bp = at_breakpoint(a);
677 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
678 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
680 bp->instr[1] = bpinstr;
681 store_inst(&bp->instr[1]);
686 printf("Sorry, no free breakpoints. Please clear one first.\n");
690 static void insert_bpts(void)
696 for (i = 0; i < NBPTS; ++i, ++bp) {
697 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
699 if (mread(bp->address, &bp->instr[0], 4) != 4) {
700 printf("Couldn't read instruction at %lx, "
701 "disabling breakpoint there\n", bp->address);
705 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
706 printf("Breakpoint at %lx is on an mtmsrd or rfid "
707 "instruction, disabling it\n", bp->address);
711 store_inst(&bp->instr[0]);
712 if (bp->enabled & BP_IABR)
714 if (mwrite(bp->address, &bpinstr, 4) != 4) {
715 printf("Couldn't write instruction at %lx, "
716 "disabling breakpoint there\n", bp->address);
717 bp->enabled &= ~BP_TRAP;
720 store_inst((void *)bp->address);
724 static void insert_cpu_bpts(void)
727 set_dabr(dabr.address | (dabr.enabled & 7));
728 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
729 set_iabr(iabr->address
730 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
733 static void remove_bpts(void)
740 for (i = 0; i < NBPTS; ++i, ++bp) {
741 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
743 if (mread(bp->address, &instr, 4) == 4
745 && mwrite(bp->address, &bp->instr, 4) != 4)
746 printf("Couldn't remove breakpoint at %lx\n",
749 store_inst((void *)bp->address);
753 static void remove_cpu_bpts(void)
756 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
760 static int branch_taken(unsigned int instr, struct pt_regs *regs)
762 unsigned int bo = (instr >> 21) & 0x1f;
766 /* decrement counter */
768 if (((bo >> 1) & 1) ^ (regs->ctr == 0))
771 if ((bo & 0x10) == 0) {
772 /* check bit from CR */
773 bi = (instr >> 16) & 0x1f;
774 if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
781 * Emulate instructions that cause a transfer of control.
782 * Returns 1 if the step was emulated, 0 if not,
783 * or -1 if the instruction is one that should not be stepped,
784 * such as an rfid, or a mtmsrd that would clear MSR_RI.
786 static int emulate_step(struct pt_regs *regs, unsigned int instr)
788 unsigned int opcode, rd;
789 unsigned long int imm;
791 opcode = instr >> 26;
794 imm = (signed short)(instr & 0xfffc);
795 if ((instr & 2) == 0)
797 regs->nip += 4; /* XXX check 32-bit mode */
799 regs->link = regs->nip;
800 if (branch_taken(instr, regs))
804 regs->gpr[9] = regs->gpr[13];
805 regs->gpr[11] = regs->nip + 4;
806 regs->gpr[12] = regs->msr & MSR_MASK;
807 regs->gpr[13] = (unsigned long) get_paca();
808 regs->nip = (unsigned long) &SystemCall_common;
809 regs->msr = MSR_KERNEL;
812 imm = instr & 0x03fffffc;
813 if (imm & 0x02000000)
815 if ((instr & 2) == 0)
818 regs->link = regs->nip + 4;
822 switch (instr & 0x7fe) {
823 case 0x20: /* bclr */
824 case 0x420: /* bcctr */
825 imm = (instr & 0x400)? regs->ctr: regs->link;
826 regs->nip += 4; /* XXX check 32-bit mode */
828 regs->link = regs->nip;
829 if (branch_taken(instr, regs))
832 case 0x24: /* rfid, scary */
833 printf("Can't single-step an rfid instruction\n");
837 rd = (instr >> 21) & 0x1f;
838 switch (instr & 0x7fe) {
839 case 0xa6: /* mfmsr */
840 regs->gpr[rd] = regs->msr & MSR_MASK;
843 case 0x164: /* mtmsrd */
844 /* only MSR_EE and MSR_RI get changed if bit 15 set */
845 /* mtmsrd doesn't change MSR_HV and MSR_ME */
846 imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
847 imm = (regs->msr & MSR_MASK & ~imm)
848 | (regs->gpr[rd] & imm);
849 if ((imm & MSR_RI) == 0) {
850 printf("Can't step an instruction that would "
862 /* Command interpreting routine */
863 static char *last_cmd;
866 cmds(struct pt_regs *excp)
874 printf("%x:", smp_processor_id());
875 #endif /* CONFIG_SMP */
882 if (last_cmd == NULL)
884 take_input(last_cmd);
918 prregs(excp); /* print regs */
966 printf("Unrecognized command: ");
968 if (' ' < cmd && cmd <= '~')
971 printf("\\x%x", cmd);
973 } while (cmd != '\n');
974 printf(" (type ? for help)\n");
981 * Step a single instruction.
982 * Some instructions we emulate, others we execute with MSR_SE set.
984 static int do_step(struct pt_regs *regs)
989 /* check we are in 64-bit kernel mode, translation enabled */
990 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
991 if (mread(regs->nip, &instr, 4) == 4) {
992 stepped = emulate_step(regs, instr);
996 regs->trap = 0xd00 | (regs->trap & 1);
997 printf("stepped to ");
998 xmon_print_symbol(regs->nip, " ", "\n");
999 ppc_inst_dump(regs->nip, 1, 0);
1004 regs->msr |= MSR_SE;
1008 static void bootcmds(void)
1014 ppc_md.restart(NULL);
1015 else if (cmd == 'h')
1017 else if (cmd == 'p')
1021 static int cpu_cmd(void)
1028 if (!scanhex(&cpu)) {
1029 /* print cpus waiting or in xmon */
1030 printf("cpus stopped:");
1032 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
1033 if (cpu_isset(cpu, cpus_in_xmon)) {
1039 printf("-%x", cpu - 1);
1044 printf("-%x", NR_CPUS - 1);
1048 /* try to switch to cpu specified */
1049 if (!cpu_isset(cpu, cpus_in_xmon)) {
1050 printf("cpu 0x%x isn't in xmon\n", cpu);
1057 while (!xmon_taken) {
1058 if (--timeout == 0) {
1059 if (test_and_set_bit(0, &xmon_taken))
1061 /* take control back */
1063 xmon_owner = smp_processor_id();
1064 printf("cpu %u didn't take control\n", cpu);
1072 #endif /* CONFIG_SMP */
1075 static unsigned short fcstab[256] = {
1076 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1077 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1078 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1079 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1080 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1081 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1082 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1083 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1084 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1085 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1086 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1087 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1088 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1089 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1090 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1091 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1092 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1093 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1094 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1095 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1096 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1097 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1098 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1099 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1100 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1101 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1102 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1103 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1104 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1105 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1106 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1107 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1110 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1119 if (!scanhex(&adrs))
1121 if (!scanhex(&ncsum))
1124 for (i = 0; i < ncsum; ++i) {
1125 if (mread(adrs+i, &v, 1) == 0) {
1126 printf("csum stopped at %x\n", adrs+i);
1131 printf("%x\n", fcs);
1135 * Check if this is a suitable place to put a breakpoint.
1137 static long check_bp_loc(unsigned long addr)
1142 if (addr < KERNELBASE) {
1143 printf("Breakpoints may only be placed at kernel addresses\n");
1146 if (!mread(addr, &instr, sizeof(instr))) {
1147 printf("Can't read instruction at address %lx\n", addr);
1150 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1151 printf("Breakpoints may not be placed on mtmsrd or rfid "
1158 static char *breakpoint_help_string =
1159 "Breakpoint command usage:\n"
1160 "b show breakpoints\n"
1161 "b <addr> [cnt] set breakpoint at given instr addr\n"
1162 "bc clear all breakpoints\n"
1163 "bc <n/addr> clear breakpoint number n or at addr\n"
1164 "bi <addr> [cnt] set hardware instr breakpoint (broken?)\n"
1165 "bd <addr> [cnt] set hardware data breakpoint (broken?)\n"
1175 const char badaddr[] = "Only kernel addresses are permitted "
1176 "for breakpoints\n";
1180 case 'd': /* bd - hardware data breakpoint */
1185 else if (cmd == 'w')
1191 if (scanhex(&dabr.address)) {
1192 if (dabr.address < KERNELBASE) {
1197 dabr.enabled = mode | BP_DABR;
1201 case 'i': /* bi - hardware instr breakpoint */
1202 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1203 printf("Hardware instruction breakpoint "
1204 "not supported on this cpu\n");
1208 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1213 if (!check_bp_loc(a))
1215 bp = new_breakpoint(a);
1217 bp->enabled |= BP_IABR | BP_IABR_TE;
1224 /* clear all breakpoints */
1225 for (i = 0; i < NBPTS; ++i)
1226 bpts[i].enabled = 0;
1229 printf("All breakpoints cleared\n");
1233 if (a <= NBPTS && a >= 1) {
1234 /* assume a breakpoint number */
1235 bp = &bpts[a-1]; /* bp nums are 1 based */
1237 /* assume a breakpoint address */
1238 bp = at_breakpoint(a);
1240 printf("No breakpoint at %x\n", a);
1245 printf("Cleared breakpoint %x (", BP_NUM(bp));
1246 xmon_print_symbol(bp->address, " ", ")\n");
1254 printf(breakpoint_help_string);
1259 /* print all breakpoints */
1260 printf(" type address\n");
1262 printf(" data %.16lx [", dabr.address);
1263 if (dabr.enabled & 1)
1265 if (dabr.enabled & 2)
1269 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1272 printf("%2x %s ", BP_NUM(bp),
1273 (bp->enabled & BP_IABR)? "inst": "trap");
1274 xmon_print_symbol(bp->address, " ", "\n");
1279 if (!check_bp_loc(a))
1281 bp = new_breakpoint(a);
1283 bp->enabled |= BP_TRAP;
1288 /* Very cheap human name for vector lookup. */
1290 const char *getvecname(unsigned long vec)
1295 case 0x100: ret = "(System Reset)"; break;
1296 case 0x200: ret = "(Machine Check)"; break;
1297 case 0x300: ret = "(Data Access)"; break;
1298 case 0x380: ret = "(Data SLB Access)"; break;
1299 case 0x400: ret = "(Instruction Access)"; break;
1300 case 0x480: ret = "(Instruction SLB Access)"; break;
1301 case 0x500: ret = "(Hardware Interrupt)"; break;
1302 case 0x600: ret = "(Alignment)"; break;
1303 case 0x700: ret = "(Program Check)"; break;
1304 case 0x800: ret = "(FPU Unavailable)"; break;
1305 case 0x900: ret = "(Decrementer)"; break;
1306 case 0xc00: ret = "(System Call)"; break;
1307 case 0xd00: ret = "(Single Step)"; break;
1308 case 0xf00: ret = "(Performance Monitor)"; break;
1309 case 0xf20: ret = "(Altivec Unavailable)"; break;
1310 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1316 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1317 unsigned long *endp)
1319 unsigned long size, offset;
1323 *startp = *endp = 0;
1326 if (setjmp(bus_error_jmp) == 0) {
1327 catch_memory_errors = 1;
1329 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1331 *startp = pc - offset;
1332 *endp = pc - offset + size;
1336 catch_memory_errors = 0;
1339 static int xmon_depth_to_print = 64;
1341 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1345 unsigned long newsp;
1346 unsigned long marker;
1348 struct pt_regs regs;
1351 if (sp < PAGE_OFFSET) {
1353 printf("SP (%lx) is in userspace\n", sp);
1357 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1358 || !mread(sp, &newsp, sizeof(unsigned long))) {
1359 printf("Couldn't read stack frame at %lx\n", sp);
1364 * For the first stack frame, try to work out if
1365 * LR and/or the saved LR value in the bottommost
1366 * stack frame are valid.
1368 if ((pc | lr) != 0) {
1369 unsigned long fnstart, fnend;
1370 unsigned long nextip;
1373 get_function_bounds(pc, &fnstart, &fnend);
1376 mread(newsp + 16, &nextip,
1377 sizeof(unsigned long));
1379 if (lr < PAGE_OFFSET
1380 || (fnstart <= lr && lr < fnend))
1382 } else if (lr == nextip) {
1384 } else if (lr >= PAGE_OFFSET
1385 && !(fnstart <= lr && lr < fnend)) {
1386 printf("[link register ] ");
1387 xmon_print_symbol(lr, " ", "\n");
1390 printf("[%.16lx] ", sp);
1391 xmon_print_symbol(ip, " ", " (unreliable)\n");
1396 printf("[%.16lx] ", sp);
1397 xmon_print_symbol(ip, " ", "\n");
1400 /* Look for "regshere" marker to see if this is
1401 an exception frame. */
1402 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1403 && marker == 0x7265677368657265ul) {
1404 if (mread(sp + 0x70, ®s, sizeof(regs))
1406 printf("Couldn't read registers at %lx\n",
1410 printf("--- Exception: %lx %s at ", regs.trap,
1411 getvecname(TRAP(®s)));
1414 xmon_print_symbol(pc, " ", "\n");
1421 } while (count++ < xmon_depth_to_print);
1424 static void backtrace(struct pt_regs *excp)
1429 xmon_show_stack(sp, 0, 0);
1431 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1435 void excprint(struct pt_regs *fp)
1440 printf("cpu 0x%x: ", smp_processor_id());
1441 #endif /* CONFIG_SMP */
1444 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1446 xmon_print_symbol(fp->nip, ": ", "\n");
1448 printf(" lr: ", fp->link);
1449 xmon_print_symbol(fp->link, ": ", "\n");
1451 printf(" sp: %lx\n", fp->gpr[1]);
1452 printf(" msr: %lx\n", fp->msr);
1454 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1455 printf(" dar: %lx\n", fp->dar);
1457 printf(" dsisr: %lx\n", fp->dsisr);
1460 printf(" current = 0x%lx\n", current);
1461 printf(" paca = 0x%lx\n", get_paca());
1463 printf(" pid = %ld, comm = %s\n",
1464 current->pid, current->comm);
1468 void prregs(struct pt_regs *fp)
1472 struct pt_regs regs;
1474 if (scanhex(&base)) {
1475 if (setjmp(bus_error_jmp) == 0) {
1476 catch_memory_errors = 1;
1478 regs = *(struct pt_regs *)base;
1482 catch_memory_errors = 0;
1483 printf("*** Error reading registers from %.16lx\n",
1487 catch_memory_errors = 0;
1491 if (FULL_REGS(fp)) {
1492 for (n = 0; n < 16; ++n)
1493 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1494 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1496 for (n = 0; n < 7; ++n)
1497 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1498 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1501 xmon_print_symbol(fp->nip, " ", "\n");
1503 xmon_print_symbol(fp->link, " ", "\n");
1504 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1505 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1506 fp->ctr, fp->xer, fp->trap);
1509 void cacheflush(void)
1512 unsigned long nflush;
1517 scanhex((void *)&adrs);
1522 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1523 if (setjmp(bus_error_jmp) == 0) {
1524 catch_memory_errors = 1;
1528 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1529 cflush((void *) adrs);
1531 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1532 cinval((void *) adrs);
1535 /* wait a little while to see if we get a machine check */
1538 catch_memory_errors = 0;
1544 unsigned int instrs[2];
1545 unsigned long (*code)(void);
1546 unsigned long opd[3];
1547 unsigned long ret = -1UL;
1549 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1550 instrs[1] = 0x4e800020;
1551 opd[0] = (unsigned long)instrs;
1555 store_inst(instrs+1);
1556 code = (unsigned long (*)(void)) opd;
1564 write_spr(int n, unsigned long val)
1566 unsigned int instrs[2];
1567 unsigned long (*code)(unsigned long);
1568 unsigned long opd[3];
1570 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1571 instrs[1] = 0x4e800020;
1572 opd[0] = (unsigned long)instrs;
1576 store_inst(instrs+1);
1577 code = (unsigned long (*)(unsigned long)) opd;
1582 static unsigned long regno;
1583 extern char exc_prolog;
1584 extern char dec_exc;
1591 #ifdef CONFIG_PPC_ISERIES
1592 struct paca_struct *ptrPaca = NULL;
1593 struct ItLpPaca *ptrLpPaca = NULL;
1594 struct ItLpRegSave *ptrLpRegSave = NULL;
1599 unsigned long sp, toc;
1600 asm("mr %0,1" : "=r" (sp) :);
1601 asm("mr %0,2" : "=r" (toc) :);
1603 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1604 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1605 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1606 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1607 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1608 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1609 #ifdef CONFIG_PPC_ISERIES
1610 // Dump out relevant Paca data areas.
1612 ptrPaca = get_paca();
1614 printf(" Local Processor Control Area (LpPaca): \n");
1615 ptrLpPaca = ptrPaca->lppaca_ptr;
1616 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1617 ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
1618 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1619 ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
1620 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
1622 printf(" Local Processor Register Save Area (LpRegSave): \n");
1623 ptrLpRegSave = ptrPaca->reg_save_ptr;
1624 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1625 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1626 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1627 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1628 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1629 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1638 val = read_spr(regno);
1640 write_spr(regno, val);
1643 printf("spr %lx = %lx\n", regno, read_spr(regno));
1655 * Stuff for reading and writing memory safely
1658 mread(unsigned long adrs, void *buf, int size)
1664 if (setjmp(bus_error_jmp) == 0) {
1665 catch_memory_errors = 1;
1671 *(short *)q = *(short *)p;
1674 *(int *)q = *(int *)p;
1677 *(long *)q = *(long *)p;
1680 for( ; n < size; ++n) {
1686 /* wait a little while to see if we get a machine check */
1690 catch_memory_errors = 0;
1695 mwrite(unsigned long adrs, void *buf, int size)
1701 if (setjmp(bus_error_jmp) == 0) {
1702 catch_memory_errors = 1;
1708 *(short *)p = *(short *)q;
1711 *(int *)p = *(int *)q;
1714 *(long *)p = *(long *)q;
1717 for ( ; n < size; ++n) {
1723 /* wait a little while to see if we get a machine check */
1727 printf("*** Error writing address %x\n", adrs + n);
1729 catch_memory_errors = 0;
1733 static int fault_type;
1734 static char *fault_chars[] = { "--", "**", "##" };
1737 handle_fault(struct pt_regs *regs)
1739 switch (TRAP(regs)) {
1751 longjmp(bus_error_jmp, 1);
1756 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1759 byterev(unsigned char *val, int size)
1765 SWAP(val[0], val[1], t);
1768 SWAP(val[0], val[3], t);
1769 SWAP(val[1], val[2], t);
1771 case 8: /* is there really any use for this? */
1772 SWAP(val[0], val[7], t);
1773 SWAP(val[1], val[6], t);
1774 SWAP(val[2], val[5], t);
1775 SWAP(val[3], val[4], t);
1783 static char *memex_help_string =
1784 "Memory examine command usage:\n"
1785 "m [addr] [flags] examine/change memory\n"
1786 " addr is optional. will start where left off.\n"
1787 " flags may include chars from this set:\n"
1788 " b modify by bytes (default)\n"
1789 " w modify by words (2 byte)\n"
1790 " l modify by longs (4 byte)\n"
1791 " d modify by doubleword (8 byte)\n"
1792 " r toggle reverse byte order mode\n"
1793 " n do not read memory (for i/o spaces)\n"
1794 " . ok to read (default)\n"
1795 "NOTE: flags are saved as defaults\n"
1798 static char *memex_subcmd_help_string =
1799 "Memory examine subcommands:\n"
1800 " hexval write this val to current location\n"
1801 " 'string' write chars from string to this location\n"
1802 " ' increment address\n"
1803 " ^ decrement address\n"
1804 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1805 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1806 " ` clear no-read flag\n"
1807 " ; stay at this addr\n"
1808 " v change to byte mode\n"
1809 " w change to word (2 byte) mode\n"
1810 " l change to long (4 byte) mode\n"
1811 " u change to doubleword (8 byte) mode\n"
1812 " m addr change current addr\n"
1813 " n toggle no-read flag\n"
1814 " r toggle byte reverse flag\n"
1815 " < count back up count bytes\n"
1816 " > count skip forward count bytes\n"
1817 " x exit this mode\n"
1823 int cmd, inc, i, nslash;
1825 unsigned char val[16];
1827 scanhex((void *)&adrs);
1830 printf(memex_help_string);
1836 while ((cmd = skipbl()) != '\n') {
1838 case 'b': size = 1; break;
1839 case 'w': size = 2; break;
1840 case 'l': size = 4; break;
1841 case 'd': size = 8; break;
1842 case 'r': brev = !brev; break;
1843 case 'n': mnoread = 1; break;
1844 case '.': mnoread = 0; break;
1853 n = mread(adrs, val, size);
1854 printf("%.16x%c", adrs, brev? 'r': ' ');
1859 for (i = 0; i < n; ++i)
1860 printf("%.2x", val[i]);
1861 for (; i < size; ++i)
1862 printf("%s", fault_chars[fault_type]);
1869 for (i = 0; i < size; ++i)
1870 val[i] = n >> (i * 8);
1873 mwrite(adrs, val, size);
1886 else if( n == '\'' )
1888 for (i = 0; i < size; ++i)
1889 val[i] = n >> (i * 8);
1892 mwrite(adrs, val, size);
1929 adrs -= 1 << nslash;
1933 adrs += 1 << nslash;
1937 adrs += 1 << -nslash;
1941 adrs -= 1 << -nslash;
1944 scanhex((void *)&adrs);
1963 printf(memex_subcmd_help_string);
1978 case 'n': c = '\n'; break;
1979 case 'r': c = '\r'; break;
1980 case 'b': c = '\b'; break;
1981 case 't': c = '\t'; break;
1986 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1987 || ('a' <= (c) && (c) <= 'f') \
1988 || ('A' <= (c) && (c) <= 'F'))
1995 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1997 scanhex((void *)&adrs);
2004 adrs += ppc_inst_dump(adrs, nidump, 1);
2010 prdump(adrs, ndump);
2017 prdump(unsigned long adrs, long ndump)
2019 long n, m, c, r, nr;
2020 unsigned char temp[16];
2022 for (n = ndump; n > 0;) {
2023 printf("%.16lx", adrs);
2026 nr = mread(adrs, temp, r);
2028 for (m = 0; m < r; ++m) {
2029 if ((m & 7) == 0 && m > 0)
2032 printf("%.2x", temp[m]);
2034 printf("%s", fault_chars[fault_type]);
2041 for (m = 0; m < r; ++m) {
2044 putchar(' ' <= c && c <= '~'? c: '.');
2058 ppc_inst_dump(unsigned long adr, long count, int praddr)
2061 unsigned long first_adr;
2062 unsigned long inst, last_inst;
2063 unsigned char val[4];
2066 for (first_adr = adr; count > 0; --count, adr += 4) {
2067 nr = mread(adr, val, 4);
2070 const char *x = fault_chars[fault_type];
2071 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2075 inst = GETWORD(val);
2076 if (adr > first_adr && inst == last_inst) {
2086 printf("%.16lx %.8x", adr, inst);
2088 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2091 return adr - first_adr;
2095 print_address(unsigned long addr)
2097 xmon_print_symbol(addr, "\t# ", "");
2102 * Memory operations - move, set, print differences
2104 static unsigned long mdest; /* destination address */
2105 static unsigned long msrc; /* source address */
2106 static unsigned long mval; /* byte value to set memory to */
2107 static unsigned long mcount; /* # bytes to affect */
2108 static unsigned long mdiffs; /* max # differences to print */
2113 scanhex((void *)&mdest);
2114 if( termch != '\n' )
2116 scanhex((void *)(cmd == 's'? &mval: &msrc));
2117 if( termch != '\n' )
2119 scanhex((void *)&mcount);
2122 memmove((void *)mdest, (void *)msrc, mcount);
2125 memset((void *)mdest, mval, mcount);
2128 if( termch != '\n' )
2130 scanhex((void *)&mdiffs);
2131 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2137 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2142 for( n = nb; n > 0; --n )
2143 if( *p1++ != *p2++ )
2144 if( ++prt <= maxpr )
2145 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2146 p1[-1], p2 - 1, p2[-1]);
2148 printf("Total of %d differences\n", prt);
2151 static unsigned mend;
2152 static unsigned mask;
2158 unsigned char val[4];
2161 scanhex((void *)&mdest);
2162 if (termch != '\n') {
2164 scanhex((void *)&mend);
2165 if (termch != '\n') {
2167 scanhex((void *)&mval);
2169 if (termch != '\n') termch = 0;
2170 scanhex((void *)&mask);
2174 for (a = mdest; a < mend; a += 4) {
2175 if (mread(a, val, 4) == 4
2176 && ((GETWORD(val) ^ mval) & mask) == 0) {
2177 printf("%.16x: %.16x\n", a, GETWORD(val));
2184 static unsigned long mskip = 0x1000;
2185 static unsigned long mlim = 0xffffffff;
2195 if (termch != '\n') termch = 0;
2197 if (termch != '\n') termch = 0;
2200 for (a = mdest; a < mlim; a += mskip) {
2201 ok = mread(a, &v, 1);
2203 printf("%.8x .. ", a);
2205 } else if (!ok && ook)
2206 printf("%.8x\n", a - mskip);
2212 printf("%.8x\n", a - mskip);
2215 /* Input scanning routines */
2226 while( c == ' ' || c == '\t' )
2232 static char *regnames[N_PTREGS] = {
2233 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2234 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2235 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2236 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2237 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2238 "trap", "dar", "dsisr", "res"
2250 /* parse register name */
2254 for (i = 0; i < sizeof(regname) - 1; ++i) {
2263 for (i = 0; i < N_PTREGS; ++i) {
2264 if (strcmp(regnames[i], regname) == 0) {
2265 if (xmon_regs == NULL) {
2266 printf("regs not available\n");
2269 *vp = ((unsigned long *)xmon_regs)[i];
2273 printf("invalid register name '%%%s'\n", regname);
2277 /* skip leading "0x" if any */
2291 } else if (c == '$') {
2293 for (i=0; i<63; i++) {
2302 *vp = kallsyms_lookup_name(tmpstr);
2304 printf("unknown symbol '%s'\n", tmpstr);
2340 if( '0' <= c && c <= '9' )
2342 if( 'A' <= c && c <= 'F' )
2343 return c - ('A' - 10);
2344 if( 'a' <= c && c <= 'f' )
2345 return c - ('a' - 10);
2350 getstring(char *s, int size)
2361 } while( c != ' ' && c != '\t' && c != '\n' );
2366 static char line[256];
2367 static char *lineptr;
2378 if (lineptr == NULL || *lineptr == 0) {
2379 if (fgets(line, sizeof(line), stdin) == NULL) {
2399 int type = inchar();
2401 static char tmp[64];
2406 xmon_print_symbol(addr, ": ", "\n");
2411 if (setjmp(bus_error_jmp) == 0) {
2412 catch_memory_errors = 1;
2414 addr = kallsyms_lookup_name(tmp);
2416 printf("%s: %lx\n", tmp, addr);
2418 printf("Symbol '%s' not found.\n", tmp);
2421 catch_memory_errors = 0;
2428 /* Print an address in numeric and symbolic form (if possible) */
2429 static void xmon_print_symbol(unsigned long address, const char *mid,
2433 const char *name = NULL;
2434 unsigned long offset, size;
2436 printf("%.16lx", address);
2437 if (setjmp(bus_error_jmp) == 0) {
2438 catch_memory_errors = 1;
2440 name = kallsyms_lookup(address, &size, &offset, &modname,
2443 /* wait a little while to see if we get a machine check */
2447 catch_memory_errors = 0;
2450 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2452 printf(" [%s]", modname);
2454 printf("%s", after);
2457 static void debug_trace(void)
2459 unsigned long val, cmd, on;
2463 /* show current state */
2465 printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
2466 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2467 on = PPCDBG_BITVAL(i) & naca->debug_switch;
2468 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2469 if (((i+1) % 3) == 0)
2475 while (cmd != '\n') {
2476 on = 1; /* default if no sign given */
2477 while (cmd == '+' || cmd == '-') {
2480 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2481 naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2482 printf("Setting all values to %s...\n", on ? "on" : "off");
2483 if (cmd == '\n') return;
2484 else cmd = skipbl();
2489 termch = cmd; /* not +/- ... let scanhex see it */
2490 scanhex((void *)&val);
2492 printf("Value %x out of range:\n", val);
2496 naca->debug_switch |= PPCDBG_BITVAL(val);
2497 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2499 naca->debug_switch &= ~PPCDBG_BITVAL(val);
2500 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2506 static void dump_slb(void)
2511 printf("SLB contents of cpu %x\n", smp_processor_id());
2513 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2514 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2515 printf("%02d %016lx ", i, tmp);
2517 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2518 printf("%016lx\n", tmp);
2522 static void dump_stab(void)
2525 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2527 printf("Segment table contents of cpu %x\n", smp_processor_id());
2529 for (i = 0; i < PAGE_SIZE/16; i++) {
2536 printf("%03d %016lx ", i, a);
2537 printf("%016lx\n", b);
2542 void xmon_init(void)
2545 __debugger_ipi = xmon_ipi;
2546 __debugger_bpt = xmon_bpt;
2547 __debugger_sstep = xmon_sstep;
2548 __debugger_iabr_match = xmon_iabr_match;
2549 __debugger_dabr_match = xmon_dabr_match;
2550 __debugger_fault_handler = xmon_fault_handler;
2553 void dump_segments(void)
2555 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)