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>
37 #define scanhex xmon_scanhex
38 #define skipbl xmon_skipbl
41 volatile cpumask_t cpus_in_xmon = CPU_MASK_NONE;
42 static unsigned long xmon_taken = 1;
43 static int xmon_owner;
45 #endif /* CONFIG_SMP */
47 #define TRAP(regs) ((regs)->trap)
48 #define FULL_REGS(regs) 1
50 static unsigned long in_xmon = 0;
52 static unsigned long adrs;
54 static unsigned long ndump = 64;
55 static unsigned long nidump = 16;
56 static unsigned long ncsum = 4096;
58 static char tmpstr[128];
60 #define JMP_BUF_LEN (184/sizeof(long))
61 static long bus_error_jmp[JMP_BUF_LEN];
62 static int catch_memory_errors;
63 static long *xmon_fault_jmp[NR_CPUS];
64 #define setjmp xmon_setjmp
65 #define longjmp xmon_longjmp
67 /* Breakpoint stuff */
69 unsigned long address;
70 unsigned int instr[2];
76 /* Bits in bpt.enabled */
77 #define BP_IABR_TE 1 /* IABR translation enabled */
83 static struct bpt bpts[NBPTS];
84 static struct bpt dabr;
85 static struct bpt *iabr;
86 static unsigned bpinstr = 0x7fe00008; /* trap */
88 #define BP_NUM(bp) ((bp) - bpts + 1)
90 /* Bits in SRR1 that are copied from MSR */
91 #define MSR_MASK 0xffffffff87c0ffff
94 static int cmds(struct pt_regs *);
95 static int mread(unsigned long, void *, int);
96 static int mwrite(unsigned long, void *, int);
97 static int handle_fault(struct pt_regs *);
98 static void byterev(unsigned char *, int);
99 static void memex(void);
100 static int bsesc(void);
101 static void dump(void);
102 static void prdump(unsigned long, long);
103 static int ppc_inst_dump(unsigned long, long, int);
104 void print_address(unsigned long);
105 static void backtrace(struct pt_regs *);
106 static void excprint(struct pt_regs *);
107 static void prregs(struct pt_regs *);
108 static void memops(int);
109 static void memlocate(void);
110 static void memzcan(void);
111 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
113 int scanhex(unsigned long *valp);
114 static void scannl(void);
115 static int hexdigit(int);
116 void getstring(char *, int);
117 static void flush_input(void);
118 static int inchar(void);
119 static void take_input(char *);
120 static unsigned long read_spr(int);
121 static void write_spr(int, unsigned long);
122 static void super_regs(void);
123 static void remove_bpts(void);
124 static void insert_bpts(void);
125 static void remove_cpu_bpts(void);
126 static void insert_cpu_bpts(void);
127 static struct bpt *at_breakpoint(unsigned long pc);
128 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
129 static int do_step(struct pt_regs *);
130 static void bpt_cmds(void);
131 static void cacheflush(void);
132 static int cpu_cmd(void);
133 static void csum(void);
134 static void bootcmds(void);
135 void dump_segments(void);
136 static void symbol_lookup(void);
137 static int emulate_step(struct pt_regs *regs, unsigned int instr);
138 static void xmon_print_symbol(unsigned long address, const char *mid,
140 static const char *getvecname(unsigned long vec);
142 static void debug_trace(void);
144 extern int print_insn_powerpc(unsigned long, unsigned long, int);
145 extern void printf(const char *fmt, ...);
146 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
147 extern int xmon_putc(int c, void *f);
148 extern int putchar(int ch);
149 extern int xmon_read_poll(void);
150 extern int setjmp(long *);
151 extern void longjmp(long *, int);
152 extern unsigned long _ASR;
153 extern char SystemCall_common[];
155 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
157 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
159 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
160 || ('a' <= (c) && (c) <= 'f') \
161 || ('A' <= (c) && (c) <= 'F'))
162 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
163 || ('a' <= (c) && (c) <= 'z') \
164 || ('A' <= (c) && (c) <= 'Z'))
165 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
167 static char *help_string = "\
169 b show breakpoints\n\
170 bd set data breakpoint\n\
171 bi set instruction breakpoint\n\
172 bc clear breakpoint\n"
175 c print cpus stopped in xmon\n\
176 c# try to switch to cpu number h (in hex)\n"
181 di dump instructions\n\
182 df dump float values\n\
183 dd dump double values\n\
184 e print exception information\n\
186 la lookup symbol+offset of specified address\n\
187 ls lookup address of specified symbol\n\
188 m examine/change memory\n\
189 mm move a block of memory\n\
190 ms set a block of memory\n\
191 md compare two blocks of memory\n\
192 ml locate a block of memory\n\
193 mz zero a block of memory\n\
194 mi show information about memory allocation\n\
195 p show the task list\n\
198 S print special registers\n\
200 T Enable/Disable PPCDBG flags\n\
201 x exit monitor and recover\n\
202 X exit monitor and dont recover\n\
203 u dump segment table or SLB\n\
210 static struct pt_regs *xmon_regs;
212 extern inline void sync(void)
214 asm volatile("sync; isync");
217 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
218 A PPC stack frame looks like this:
225 Parameter save area (SP+48)
226 TOC save area (SP+40)
227 link editor doubleword (SP+32)
228 compiler doubleword (SP+24)
233 Note that the LR (ret addr) may not be saved in the current frame if
234 no functions have been called from the current function.
238 * We don't allow single-stepping an mtmsrd that would clear
239 * MSR_RI, since that would make the exception unrecoverable.
240 * Since we need to single-step to proceed from a breakpoint,
241 * we don't allow putting a breakpoint on an mtmsrd instruction.
242 * Similarly we don't allow breakpoints on rfid instructions.
243 * These macros tell us if an instruction is a mtmsrd or rfid.
245 #define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
246 #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
249 * Disable surveillance (the service processor watchdog function)
250 * while we are in xmon.
251 * XXX we should re-enable it when we leave. :)
253 #define SURVEILLANCE_TOKEN 9000
255 static inline void disable_surveillance(void)
257 #ifndef CONFIG_PPC_ISERIES
258 /* Since this can't be a module, args should end up below 4GB. */
259 static struct rtas_args args;
261 if (systemcfg->platform & PLATFORM_PSERIES) {
263 * At this point we have got all the cpus we can into
264 * xmon, so there is hopefully no other cpu calling RTAS
265 * at the moment, even though we don't take rtas.lock.
266 * If we did try to take rtas.lock there would be a
267 * real possibility of deadlock.
269 args.token = rtas_token("set-indicator");
270 if (args.token == RTAS_UNKNOWN_SERVICE)
274 args.rets = &args.args[3];
275 args.args[0] = SURVEILLANCE_TOKEN;
278 enter_rtas(__pa(&args));
284 static int xmon_speaker;
286 static void get_output_lock(void)
288 int me = smp_processor_id() + 0x100;
289 int last_speaker = 0, prev;
292 if (xmon_speaker == me)
295 if (xmon_speaker == 0) {
296 last_speaker = cmpxchg(&xmon_speaker, 0, me);
297 if (last_speaker == 0)
301 while (xmon_speaker == last_speaker) {
304 /* hostile takeover */
305 prev = cmpxchg(&xmon_speaker, last_speaker, me);
306 if (prev == last_speaker)
313 static void release_output_lock(void)
319 int xmon_core(struct pt_regs *regs, int fromipi)
324 long recurse_jmp[JMP_BUF_LEN];
325 unsigned long offset;
329 unsigned long timeout;
333 set_msrd(msr & ~MSR_EE); /* disable interrupts */
335 bp = in_breakpoint_table(regs->nip, &offset);
337 regs->nip = bp->address + offset;
338 atomic_dec(&bp->ref_count);
344 cpu = smp_processor_id();
345 if (cpu_isset(cpu, cpus_in_xmon)) {
348 printf("cpu 0x%x: Exception %lx %s in xmon, "
349 "returning to main loop\n",
350 cpu, regs->trap, getvecname(TRAP(regs)));
351 longjmp(xmon_fault_jmp[cpu], 1);
354 if (setjmp(recurse_jmp) != 0) {
355 if (!in_xmon || !xmon_gate) {
356 printf("xmon: WARNING: bad recursive fault "
357 "on cpu 0x%x\n", cpu);
360 secondary = !(xmon_taken && cpu == xmon_owner);
364 xmon_fault_jmp[cpu] = recurse_jmp;
365 cpu_set(cpu, cpus_in_xmon);
368 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
369 bp = at_breakpoint(regs->nip);
370 if (bp || (regs->msr & MSR_RI) == 0)
377 printf("cpu 0x%x stopped at breakpoint 0x%x (",
379 xmon_print_symbol(regs->nip, " ", ")\n");
381 if ((regs->msr & MSR_RI) == 0)
382 printf("WARNING: exception is not recoverable, "
384 release_output_lock();
389 while (secondary && !xmon_gate) {
393 secondary = test_and_set_bit(0, &in_xmon);
398 if (!secondary && !xmon_gate) {
399 /* we are the first cpu to come in */
400 /* interrupt other cpu(s) */
401 int ncpus = num_online_cpus();
406 smp_send_debugger_break(MSG_ALL_BUT_SELF);
407 /* wait for other cpus to come in */
408 for (timeout = 100000000; timeout != 0; --timeout)
409 if (cpus_weight(cpus_in_xmon) >= ncpus)
413 disable_surveillance();
414 /* for breakpoint or single step, print the current instr. */
415 if (bp || TRAP(regs) == 0xd00)
416 ppc_inst_dump(regs->nip, 1, 0);
417 printf("enter ? for help\n");
426 if (cpu == xmon_owner) {
427 if (!test_and_set_bit(0, &xmon_taken)) {
432 while (cpu == xmon_owner)
446 /* have switched to some other cpu */
451 cpu_clear(cpu, cpus_in_xmon);
452 xmon_fault_jmp[cpu] = NULL;
455 /* UP is simple... */
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;
466 bp = at_breakpoint(regs->nip);
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, "
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");
488 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
489 bp = at_breakpoint(regs->nip);
491 int stepped = emulate_step(regs, bp->instr[0]);
493 regs->nip = (unsigned long) &bp->instr[0];
494 atomic_inc(&bp->ref_count);
501 set_msrd(msr); /* restore interrupt enable */
506 int xmon(struct pt_regs *excp)
511 /* Ok, grab regs as they are now.
512 This won't do a particularily good job because the
513 prologue has already been executed.
514 ToDo: We could reach back into the callers save
515 area to do a better job of representing the
518 asm volatile ("std 0,0(%0)\n\
549 std 31,248(%0)" : : "b" (®s));
551 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
552 regs.msr = get_msr();
553 regs.ctr = get_ctr();
554 regs.xer = get_xer();
559 return xmon_core(excp, 0);
562 int xmon_bpt(struct pt_regs *regs)
565 unsigned long offset;
567 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
570 /* Are we at the trap at bp->instr[1] for some bp? */
571 bp = in_breakpoint_table(regs->nip, &offset);
572 if (bp != NULL && offset == 4) {
573 regs->nip = bp->address + 4;
574 atomic_dec(&bp->ref_count);
578 /* Are we at a breakpoint? */
579 bp = at_breakpoint(regs->nip);
588 int xmon_sstep(struct pt_regs *regs)
596 int xmon_dabr_match(struct pt_regs *regs)
598 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
604 int xmon_iabr_match(struct pt_regs *regs)
606 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
614 int xmon_ipi(struct pt_regs *regs)
617 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
623 int xmon_fault_handler(struct pt_regs *regs)
626 unsigned long offset;
628 if (in_xmon && catch_memory_errors)
629 handle_fault(regs); /* doesn't return */
631 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
632 bp = in_breakpoint_table(regs->nip, &offset);
634 regs->nip = bp->address + offset;
635 atomic_dec(&bp->ref_count);
643 static struct bpt *at_breakpoint(unsigned long pc)
649 for (i = 0; i < NBPTS; ++i, ++bp)
650 if (bp->enabled && pc == bp->address)
655 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
659 off = nip - (unsigned long) bpts;
660 if (off >= sizeof(bpts))
662 off %= sizeof(struct bpt);
663 if (off != offsetof(struct bpt, instr[0])
664 && off != offsetof(struct bpt, instr[1]))
666 *offp = off - offsetof(struct bpt, instr[0]);
667 return (struct bpt *) (nip - off);
670 static struct bpt *new_breakpoint(unsigned long a)
675 bp = at_breakpoint(a);
679 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
680 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
682 bp->instr[1] = bpinstr;
683 store_inst(&bp->instr[1]);
688 printf("Sorry, no free breakpoints. Please clear one first.\n");
692 static void insert_bpts(void)
698 for (i = 0; i < NBPTS; ++i, ++bp) {
699 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
701 if (mread(bp->address, &bp->instr[0], 4) != 4) {
702 printf("Couldn't read instruction at %lx, "
703 "disabling breakpoint there\n", bp->address);
707 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
708 printf("Breakpoint at %lx is on an mtmsrd or rfid "
709 "instruction, disabling it\n", bp->address);
713 store_inst(&bp->instr[0]);
714 if (bp->enabled & BP_IABR)
716 if (mwrite(bp->address, &bpinstr, 4) != 4) {
717 printf("Couldn't write instruction at %lx, "
718 "disabling breakpoint there\n", bp->address);
719 bp->enabled &= ~BP_TRAP;
722 store_inst((void *)bp->address);
726 static void insert_cpu_bpts(void)
729 set_dabr(dabr.address | (dabr.enabled & 7));
730 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
731 set_iabr(iabr->address
732 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
735 static void remove_bpts(void)
742 for (i = 0; i < NBPTS; ++i, ++bp) {
743 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
745 if (mread(bp->address, &instr, 4) == 4
747 && mwrite(bp->address, &bp->instr, 4) != 4)
748 printf("Couldn't remove breakpoint at %lx\n",
751 store_inst((void *)bp->address);
755 static void remove_cpu_bpts(void)
758 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
762 static int branch_taken(unsigned int instr, struct pt_regs *regs)
764 unsigned int bo = (instr >> 21) & 0x1f;
768 /* decrement counter */
770 if (((bo >> 1) & 1) ^ (regs->ctr == 0))
773 if ((bo & 0x10) == 0) {
774 /* check bit from CR */
775 bi = (instr >> 16) & 0x1f;
776 if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
783 * Emulate instructions that cause a transfer of control.
784 * Returns 1 if the step was emulated, 0 if not,
785 * or -1 if the instruction is one that should not be stepped,
786 * such as an rfid, or a mtmsrd that would clear MSR_RI.
788 static int emulate_step(struct pt_regs *regs, unsigned int instr)
790 unsigned int opcode, rd;
791 unsigned long int imm;
793 opcode = instr >> 26;
796 imm = (signed short)(instr & 0xfffc);
797 if ((instr & 2) == 0)
799 regs->nip += 4; /* XXX check 32-bit mode */
801 regs->link = regs->nip;
802 if (branch_taken(instr, regs))
806 regs->gpr[9] = regs->gpr[13];
807 regs->gpr[11] = regs->nip + 4;
808 regs->gpr[12] = regs->msr & MSR_MASK;
809 regs->gpr[13] = (unsigned long) get_paca();
810 regs->nip = (unsigned long) &SystemCall_common;
811 regs->msr = MSR_KERNEL;
814 imm = instr & 0x03fffffc;
815 if (imm & 0x02000000)
817 if ((instr & 2) == 0)
820 regs->link = regs->nip + 4;
824 switch (instr & 0x7fe) {
825 case 0x20: /* bclr */
826 case 0x420: /* bcctr */
827 imm = (instr & 0x400)? regs->ctr: regs->link;
828 regs->nip += 4; /* XXX check 32-bit mode */
830 regs->link = regs->nip;
831 if (branch_taken(instr, regs))
834 case 0x24: /* rfid, scary */
835 printf("Can't single-step an rfid instruction\n");
839 rd = (instr >> 21) & 0x1f;
840 switch (instr & 0x7fe) {
841 case 0xa6: /* mfmsr */
842 regs->gpr[rd] = regs->msr & MSR_MASK;
845 case 0x164: /* mtmsrd */
846 /* only MSR_EE and MSR_RI get changed if bit 15 set */
847 /* mtmsrd doesn't change MSR_HV and MSR_ME */
848 imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
849 imm = (regs->msr & MSR_MASK & ~imm)
850 | (regs->gpr[rd] & imm);
851 if ((imm & MSR_RI) == 0) {
852 printf("Can't step an instruction that would "
864 /* Command interpreting routine */
865 static char *last_cmd;
868 cmds(struct pt_regs *excp)
876 printf("%x:", smp_processor_id());
877 #endif /* CONFIG_SMP */
884 if (last_cmd == NULL)
886 take_input(last_cmd);
920 prregs(excp); /* print regs */
968 printf("Unrecognized command: ");
970 if (' ' < cmd && cmd <= '~')
973 printf("\\x%x", cmd);
975 } while (cmd != '\n');
976 printf(" (type ? for help)\n");
983 * Step a single instruction.
984 * Some instructions we emulate, others we execute with MSR_SE set.
986 static int do_step(struct pt_regs *regs)
991 /* check we are in 64-bit kernel mode, translation enabled */
992 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
993 if (mread(regs->nip, &instr, 4) == 4) {
994 stepped = emulate_step(regs, instr);
998 regs->trap = 0xd00 | (regs->trap & 1);
999 printf("stepped to ");
1000 xmon_print_symbol(regs->nip, " ", "\n");
1001 ppc_inst_dump(regs->nip, 1, 0);
1006 regs->msr |= MSR_SE;
1010 static void bootcmds(void)
1016 ppc_md.restart(NULL);
1017 else if (cmd == 'h')
1019 else if (cmd == 'p')
1023 static int cpu_cmd(void)
1030 if (!scanhex(&cpu)) {
1031 /* print cpus waiting or in xmon */
1032 printf("cpus stopped:");
1034 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
1035 if (cpu_isset(cpu, cpus_in_xmon)) {
1041 printf("-%x", cpu - 1);
1046 printf("-%x", NR_CPUS - 1);
1050 /* try to switch to cpu specified */
1051 if (!cpu_isset(cpu, cpus_in_xmon)) {
1052 printf("cpu 0x%x isn't in xmon\n", cpu);
1059 while (!xmon_taken) {
1060 if (--timeout == 0) {
1061 if (test_and_set_bit(0, &xmon_taken))
1063 /* take control back */
1065 xmon_owner = smp_processor_id();
1066 printf("cpu %u didn't take control\n", cpu);
1074 #endif /* CONFIG_SMP */
1077 static unsigned short fcstab[256] = {
1078 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1079 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1080 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1081 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1082 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1083 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1084 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1085 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1086 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1087 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1088 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1089 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1090 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1091 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1092 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1093 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1094 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1095 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1096 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1097 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1098 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1099 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1100 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1101 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1102 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1103 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1104 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1105 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1106 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1107 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1108 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1109 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1112 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1121 if (!scanhex(&adrs))
1123 if (!scanhex(&ncsum))
1126 for (i = 0; i < ncsum; ++i) {
1127 if (mread(adrs+i, &v, 1) == 0) {
1128 printf("csum stopped at %x\n", adrs+i);
1133 printf("%x\n", fcs);
1137 * Check if this is a suitable place to put a breakpoint.
1139 static long check_bp_loc(unsigned long addr)
1144 if (addr < KERNELBASE) {
1145 printf("Breakpoints may only be placed at kernel addresses\n");
1148 if (!mread(addr, &instr, sizeof(instr))) {
1149 printf("Can't read instruction at address %lx\n", addr);
1152 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1153 printf("Breakpoints may not be placed on mtmsrd or rfid "
1160 static char *breakpoint_help_string =
1161 "Breakpoint command usage:\n"
1162 "b show breakpoints\n"
1163 "b <addr> [cnt] set breakpoint at given instr addr\n"
1164 "bc clear all breakpoints\n"
1165 "bc <n/addr> clear breakpoint number n or at addr\n"
1166 "bi <addr> [cnt] set hardware instr breakpoint (broken?)\n"
1167 "bd <addr> [cnt] set hardware data breakpoint (broken?)\n"
1177 const char badaddr[] = "Only kernel addresses are permitted "
1178 "for breakpoints\n";
1182 case 'd': /* bd - hardware data breakpoint */
1187 else if (cmd == 'w')
1193 if (scanhex(&dabr.address)) {
1194 if (dabr.address < KERNELBASE) {
1199 dabr.enabled = mode | BP_DABR;
1203 case 'i': /* bi - hardware instr breakpoint */
1204 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1205 printf("Hardware instruction breakpoint "
1206 "not supported on this cpu\n");
1210 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1215 if (!check_bp_loc(a))
1217 bp = new_breakpoint(a);
1219 bp->enabled |= BP_IABR | BP_IABR_TE;
1226 /* clear all breakpoints */
1227 for (i = 0; i < NBPTS; ++i)
1228 bpts[i].enabled = 0;
1231 printf("All breakpoints cleared\n");
1235 if (a <= NBPTS && a >= 1) {
1236 /* assume a breakpoint number */
1237 bp = &bpts[a-1]; /* bp nums are 1 based */
1239 /* assume a breakpoint address */
1240 bp = at_breakpoint(a);
1242 printf("No breakpoint at %x\n", a);
1247 printf("Cleared breakpoint %x (", BP_NUM(bp));
1248 xmon_print_symbol(bp->address, " ", ")\n");
1256 printf(breakpoint_help_string);
1261 /* print all breakpoints */
1262 printf(" type address\n");
1264 printf(" data %.16lx [", dabr.address);
1265 if (dabr.enabled & 1)
1267 if (dabr.enabled & 2)
1271 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1274 printf("%2x %s ", BP_NUM(bp),
1275 (bp->enabled & BP_IABR)? "inst": "trap");
1276 xmon_print_symbol(bp->address, " ", "\n");
1281 if (!check_bp_loc(a))
1283 bp = new_breakpoint(a);
1285 bp->enabled |= BP_TRAP;
1290 /* Very cheap human name for vector lookup. */
1292 const char *getvecname(unsigned long vec)
1297 case 0x100: ret = "(System Reset)"; break;
1298 case 0x200: ret = "(Machine Check)"; break;
1299 case 0x300: ret = "(Data Access)"; break;
1300 case 0x380: ret = "(Data SLB Access)"; break;
1301 case 0x400: ret = "(Instruction Access)"; break;
1302 case 0x480: ret = "(Instruction SLB Access)"; break;
1303 case 0x500: ret = "(Hardware Interrupt)"; break;
1304 case 0x600: ret = "(Alignment)"; break;
1305 case 0x700: ret = "(Program Check)"; break;
1306 case 0x800: ret = "(FPU Unavailable)"; break;
1307 case 0x900: ret = "(Decrementer)"; break;
1308 case 0xc00: ret = "(System Call)"; break;
1309 case 0xd00: ret = "(Single Step)"; break;
1310 case 0xf00: ret = "(Performance Monitor)"; break;
1311 case 0xf20: ret = "(Altivec Unavailable)"; break;
1312 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1318 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1319 unsigned long *endp)
1321 unsigned long size, offset;
1325 *startp = *endp = 0;
1328 if (setjmp(bus_error_jmp) == 0) {
1329 catch_memory_errors = 1;
1331 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1333 *startp = pc - offset;
1334 *endp = pc - offset + size;
1338 catch_memory_errors = 0;
1341 static int xmon_depth_to_print = 64;
1343 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1347 unsigned long newsp;
1348 unsigned long marker;
1350 struct pt_regs regs;
1353 if (sp < PAGE_OFFSET) {
1355 printf("SP (%lx) is in userspace\n", sp);
1359 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1360 || !mread(sp, &newsp, sizeof(unsigned long))) {
1361 printf("Couldn't read stack frame at %lx\n", sp);
1366 * For the first stack frame, try to work out if
1367 * LR and/or the saved LR value in the bottommost
1368 * stack frame are valid.
1370 if ((pc | lr) != 0) {
1371 unsigned long fnstart, fnend;
1372 unsigned long nextip;
1375 get_function_bounds(pc, &fnstart, &fnend);
1378 mread(newsp + 16, &nextip,
1379 sizeof(unsigned long));
1381 if (lr < PAGE_OFFSET
1382 || (fnstart <= lr && lr < fnend))
1384 } else if (lr == nextip) {
1386 } else if (lr >= PAGE_OFFSET
1387 && !(fnstart <= lr && lr < fnend)) {
1388 printf("[link register ] ");
1389 xmon_print_symbol(lr, " ", "\n");
1392 printf("[%.16lx] ", sp);
1393 xmon_print_symbol(ip, " ", " (unreliable)\n");
1398 printf("[%.16lx] ", sp);
1399 xmon_print_symbol(ip, " ", "\n");
1402 /* Look for "regshere" marker to see if this is
1403 an exception frame. */
1404 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1405 && marker == 0x7265677368657265ul) {
1406 if (mread(sp + 0x70, ®s, sizeof(regs))
1408 printf("Couldn't read registers at %lx\n",
1412 printf("--- Exception: %lx %s at ", regs.trap,
1413 getvecname(TRAP(®s)));
1416 xmon_print_symbol(pc, " ", "\n");
1423 } while (count++ < xmon_depth_to_print);
1426 static void backtrace(struct pt_regs *excp)
1431 xmon_show_stack(sp, 0, 0);
1433 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1437 void excprint(struct pt_regs *fp)
1442 printf("cpu 0x%x: ", smp_processor_id());
1443 #endif /* CONFIG_SMP */
1446 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1448 xmon_print_symbol(fp->nip, ": ", "\n");
1450 printf(" lr: ", fp->link);
1451 xmon_print_symbol(fp->link, ": ", "\n");
1453 printf(" sp: %lx\n", fp->gpr[1]);
1454 printf(" msr: %lx\n", fp->msr);
1456 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1457 printf(" dar: %lx\n", fp->dar);
1459 printf(" dsisr: %lx\n", fp->dsisr);
1462 printf(" current = 0x%lx\n", current);
1463 printf(" paca = 0x%lx\n", get_paca());
1465 printf(" pid = %ld, comm = %s\n",
1466 current->pid, current->comm);
1470 void prregs(struct pt_regs *fp)
1474 struct pt_regs regs;
1476 if (scanhex(&base)) {
1477 if (setjmp(bus_error_jmp) == 0) {
1478 catch_memory_errors = 1;
1480 regs = *(struct pt_regs *)base;
1484 catch_memory_errors = 0;
1485 printf("*** Error reading registers from %.16lx\n",
1489 catch_memory_errors = 0;
1493 if (FULL_REGS(fp)) {
1494 for (n = 0; n < 16; ++n)
1495 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1496 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1498 for (n = 0; n < 7; ++n)
1499 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1500 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1503 xmon_print_symbol(fp->nip, " ", "\n");
1505 xmon_print_symbol(fp->link, " ", "\n");
1506 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1507 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1508 fp->ctr, fp->xer, fp->trap);
1511 void cacheflush(void)
1514 unsigned long nflush;
1519 scanhex((void *)&adrs);
1524 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1525 if (setjmp(bus_error_jmp) == 0) {
1526 catch_memory_errors = 1;
1530 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1531 cflush((void *) adrs);
1533 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1534 cinval((void *) adrs);
1537 /* wait a little while to see if we get a machine check */
1540 catch_memory_errors = 0;
1546 unsigned int instrs[2];
1547 unsigned long (*code)(void);
1548 unsigned long opd[3];
1549 unsigned long ret = -1UL;
1551 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1552 instrs[1] = 0x4e800020;
1553 opd[0] = (unsigned long)instrs;
1557 store_inst(instrs+1);
1558 code = (unsigned long (*)(void)) opd;
1566 write_spr(int n, unsigned long val)
1568 unsigned int instrs[2];
1569 unsigned long (*code)(unsigned long);
1570 unsigned long opd[3];
1572 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1573 instrs[1] = 0x4e800020;
1574 opd[0] = (unsigned long)instrs;
1578 store_inst(instrs+1);
1579 code = (unsigned long (*)(unsigned long)) opd;
1584 static unsigned long regno;
1585 extern char exc_prolog;
1586 extern char dec_exc;
1593 #ifdef CONFIG_PPC_ISERIES
1594 struct paca_struct *ptrPaca = NULL;
1595 struct ItLpPaca *ptrLpPaca = NULL;
1596 struct ItLpRegSave *ptrLpRegSave = NULL;
1601 unsigned long sp, toc;
1602 asm("mr %0,1" : "=r" (sp) :);
1603 asm("mr %0,2" : "=r" (toc) :);
1605 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1606 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1607 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1608 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1609 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1610 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1611 #ifdef CONFIG_PPC_ISERIES
1612 // Dump out relevant Paca data areas.
1614 ptrPaca = get_paca();
1616 printf(" Local Processor Control Area (LpPaca): \n");
1617 ptrLpPaca = ptrPaca->xLpPacaPtr;
1618 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1619 ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
1620 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1621 ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
1622 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
1624 printf(" Local Processor Register Save Area (LpRegSave): \n");
1625 ptrLpRegSave = ptrPaca->xLpRegSavePtr;
1626 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1627 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1628 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1629 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1630 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1631 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1640 val = read_spr(regno);
1642 write_spr(regno, val);
1645 printf("spr %lx = %lx\n", regno, read_spr(regno));
1657 * Stuff for reading and writing memory safely
1660 mread(unsigned long adrs, void *buf, int size)
1666 if (setjmp(bus_error_jmp) == 0) {
1667 catch_memory_errors = 1;
1673 *(short *)q = *(short *)p;
1676 *(int *)q = *(int *)p;
1679 *(long *)q = *(long *)p;
1682 for( ; n < size; ++n) {
1688 /* wait a little while to see if we get a machine check */
1692 catch_memory_errors = 0;
1697 mwrite(unsigned long adrs, void *buf, int size)
1703 if (setjmp(bus_error_jmp) == 0) {
1704 catch_memory_errors = 1;
1710 *(short *)p = *(short *)q;
1713 *(int *)p = *(int *)q;
1716 *(long *)p = *(long *)q;
1719 for ( ; n < size; ++n) {
1725 /* wait a little while to see if we get a machine check */
1729 printf("*** Error writing address %x\n", adrs + n);
1731 catch_memory_errors = 0;
1735 static int fault_type;
1736 static char *fault_chars[] = { "--", "**", "##" };
1739 handle_fault(struct pt_regs *regs)
1741 switch (TRAP(regs)) {
1753 longjmp(bus_error_jmp, 1);
1758 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1761 byterev(unsigned char *val, int size)
1767 SWAP(val[0], val[1], t);
1770 SWAP(val[0], val[3], t);
1771 SWAP(val[1], val[2], t);
1773 case 8: /* is there really any use for this? */
1774 SWAP(val[0], val[7], t);
1775 SWAP(val[1], val[6], t);
1776 SWAP(val[2], val[5], t);
1777 SWAP(val[3], val[4], t);
1785 static char *memex_help_string =
1786 "Memory examine command usage:\n"
1787 "m [addr] [flags] examine/change memory\n"
1788 " addr is optional. will start where left off.\n"
1789 " flags may include chars from this set:\n"
1790 " b modify by bytes (default)\n"
1791 " w modify by words (2 byte)\n"
1792 " l modify by longs (4 byte)\n"
1793 " d modify by doubleword (8 byte)\n"
1794 " r toggle reverse byte order mode\n"
1795 " n do not read memory (for i/o spaces)\n"
1796 " . ok to read (default)\n"
1797 "NOTE: flags are saved as defaults\n"
1800 static char *memex_subcmd_help_string =
1801 "Memory examine subcommands:\n"
1802 " hexval write this val to current location\n"
1803 " 'string' write chars from string to this location\n"
1804 " ' increment address\n"
1805 " ^ decrement address\n"
1806 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1807 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1808 " ` clear no-read flag\n"
1809 " ; stay at this addr\n"
1810 " v change to byte mode\n"
1811 " w change to word (2 byte) mode\n"
1812 " l change to long (4 byte) mode\n"
1813 " u change to doubleword (8 byte) mode\n"
1814 " m addr change current addr\n"
1815 " n toggle no-read flag\n"
1816 " r toggle byte reverse flag\n"
1817 " < count back up count bytes\n"
1818 " > count skip forward count bytes\n"
1819 " x exit this mode\n"
1825 int cmd, inc, i, nslash;
1827 unsigned char val[16];
1829 scanhex((void *)&adrs);
1832 printf(memex_help_string);
1838 while ((cmd = skipbl()) != '\n') {
1840 case 'b': size = 1; break;
1841 case 'w': size = 2; break;
1842 case 'l': size = 4; break;
1843 case 'd': size = 8; break;
1844 case 'r': brev = !brev; break;
1845 case 'n': mnoread = 1; break;
1846 case '.': mnoread = 0; break;
1855 n = mread(adrs, val, size);
1856 printf("%.16x%c", adrs, brev? 'r': ' ');
1861 for (i = 0; i < n; ++i)
1862 printf("%.2x", val[i]);
1863 for (; i < size; ++i)
1864 printf("%s", fault_chars[fault_type]);
1871 for (i = 0; i < size; ++i)
1872 val[i] = n >> (i * 8);
1875 mwrite(adrs, val, size);
1888 else if( n == '\'' )
1890 for (i = 0; i < size; ++i)
1891 val[i] = n >> (i * 8);
1894 mwrite(adrs, val, size);
1931 adrs -= 1 << nslash;
1935 adrs += 1 << nslash;
1939 adrs += 1 << -nslash;
1943 adrs -= 1 << -nslash;
1946 scanhex((void *)&adrs);
1965 printf(memex_subcmd_help_string);
1980 case 'n': c = '\n'; break;
1981 case 'r': c = '\r'; break;
1982 case 'b': c = '\b'; break;
1983 case 't': c = '\t'; break;
1988 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1989 || ('a' <= (c) && (c) <= 'f') \
1990 || ('A' <= (c) && (c) <= 'F'))
1997 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1999 scanhex((void *)&adrs);
2006 adrs += ppc_inst_dump(adrs, nidump, 1);
2012 prdump(adrs, ndump);
2019 prdump(unsigned long adrs, long ndump)
2021 long n, m, c, r, nr;
2022 unsigned char temp[16];
2024 for (n = ndump; n > 0;) {
2025 printf("%.16lx", adrs);
2028 nr = mread(adrs, temp, r);
2030 for (m = 0; m < r; ++m) {
2031 if ((m & 7) == 0 && m > 0)
2034 printf("%.2x", temp[m]);
2036 printf("%s", fault_chars[fault_type]);
2043 for (m = 0; m < r; ++m) {
2046 putchar(' ' <= c && c <= '~'? c: '.');
2060 ppc_inst_dump(unsigned long adr, long count, int praddr)
2063 unsigned long first_adr;
2064 unsigned long inst, last_inst;
2065 unsigned char val[4];
2068 for (first_adr = adr; count > 0; --count, adr += 4) {
2069 nr = mread(adr, val, 4);
2072 const char *x = fault_chars[fault_type];
2073 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2077 inst = GETWORD(val);
2078 if (adr > first_adr && inst == last_inst) {
2088 printf("%.16lx %.8x", adr, inst);
2090 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2093 return adr - first_adr;
2097 print_address(unsigned long addr)
2099 xmon_print_symbol(addr, "\t# ", "");
2104 * Memory operations - move, set, print differences
2106 static unsigned long mdest; /* destination address */
2107 static unsigned long msrc; /* source address */
2108 static unsigned long mval; /* byte value to set memory to */
2109 static unsigned long mcount; /* # bytes to affect */
2110 static unsigned long mdiffs; /* max # differences to print */
2115 scanhex((void *)&mdest);
2116 if( termch != '\n' )
2118 scanhex((void *)(cmd == 's'? &mval: &msrc));
2119 if( termch != '\n' )
2121 scanhex((void *)&mcount);
2124 memmove((void *)mdest, (void *)msrc, mcount);
2127 memset((void *)mdest, mval, mcount);
2130 if( termch != '\n' )
2132 scanhex((void *)&mdiffs);
2133 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2139 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2144 for( n = nb; n > 0; --n )
2145 if( *p1++ != *p2++ )
2146 if( ++prt <= maxpr )
2147 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2148 p1[-1], p2 - 1, p2[-1]);
2150 printf("Total of %d differences\n", prt);
2153 static unsigned mend;
2154 static unsigned mask;
2160 unsigned char val[4];
2163 scanhex((void *)&mdest);
2164 if (termch != '\n') {
2166 scanhex((void *)&mend);
2167 if (termch != '\n') {
2169 scanhex((void *)&mval);
2171 if (termch != '\n') termch = 0;
2172 scanhex((void *)&mask);
2176 for (a = mdest; a < mend; a += 4) {
2177 if (mread(a, val, 4) == 4
2178 && ((GETWORD(val) ^ mval) & mask) == 0) {
2179 printf("%.16x: %.16x\n", a, GETWORD(val));
2186 static unsigned long mskip = 0x1000;
2187 static unsigned long mlim = 0xffffffff;
2197 if (termch != '\n') termch = 0;
2199 if (termch != '\n') termch = 0;
2202 for (a = mdest; a < mlim; a += mskip) {
2203 ok = mread(a, &v, 1);
2205 printf("%.8x .. ", a);
2207 } else if (!ok && ook)
2208 printf("%.8x\n", a - mskip);
2214 printf("%.8x\n", a - mskip);
2217 /* Input scanning routines */
2228 while( c == ' ' || c == '\t' )
2234 static char *regnames[N_PTREGS] = {
2235 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2236 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2237 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2238 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2239 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2240 "trap", "dar", "dsisr", "res"
2252 /* parse register name */
2256 for (i = 0; i < sizeof(regname) - 1; ++i) {
2265 for (i = 0; i < N_PTREGS; ++i) {
2266 if (strcmp(regnames[i], regname) == 0) {
2267 if (xmon_regs == NULL) {
2268 printf("regs not available\n");
2271 *vp = ((unsigned long *)xmon_regs)[i];
2275 printf("invalid register name '%%%s'\n", regname);
2279 /* skip leading "0x" if any */
2293 } else if (c == '$') {
2295 for (i=0; i<63; i++) {
2304 *vp = kallsyms_lookup_name(tmpstr);
2306 printf("unknown symbol '%s'\n", tmpstr);
2342 if( '0' <= c && c <= '9' )
2344 if( 'A' <= c && c <= 'F' )
2345 return c - ('A' - 10);
2346 if( 'a' <= c && c <= 'f' )
2347 return c - ('a' - 10);
2352 getstring(char *s, int size)
2363 } while( c != ' ' && c != '\t' && c != '\n' );
2368 static char line[256];
2369 static char *lineptr;
2380 if (lineptr == NULL || *lineptr == 0) {
2381 if (fgets(line, sizeof(line), stdin) == NULL) {
2401 int type = inchar();
2403 static char tmp[64];
2408 xmon_print_symbol(addr, ": ", "\n");
2413 if (setjmp(bus_error_jmp) == 0) {
2414 catch_memory_errors = 1;
2416 addr = kallsyms_lookup_name(tmp);
2418 printf("%s: %lx\n", tmp, addr);
2420 printf("Symbol '%s' not found.\n", tmp);
2423 catch_memory_errors = 0;
2430 /* Print an address in numeric and symbolic form (if possible) */
2431 static void xmon_print_symbol(unsigned long address, const char *mid,
2435 const char *name = NULL;
2436 unsigned long offset, size;
2438 printf("%.16lx", address);
2439 if (setjmp(bus_error_jmp) == 0) {
2440 catch_memory_errors = 1;
2442 name = kallsyms_lookup(address, &size, &offset, &modname,
2445 /* wait a little while to see if we get a machine check */
2449 catch_memory_errors = 0;
2452 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2454 printf(" [%s]", modname);
2456 printf("%s", after);
2459 static void debug_trace(void)
2461 unsigned long val, cmd, on;
2465 /* show current state */
2467 printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
2468 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2469 on = PPCDBG_BITVAL(i) & naca->debug_switch;
2470 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2471 if (((i+1) % 3) == 0)
2477 while (cmd != '\n') {
2478 on = 1; /* default if no sign given */
2479 while (cmd == '+' || cmd == '-') {
2482 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2483 naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2484 printf("Setting all values to %s...\n", on ? "on" : "off");
2485 if (cmd == '\n') return;
2486 else cmd = skipbl();
2491 termch = cmd; /* not +/- ... let scanhex see it */
2492 scanhex((void *)&val);
2494 printf("Value %x out of range:\n", val);
2498 naca->debug_switch |= PPCDBG_BITVAL(val);
2499 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2501 naca->debug_switch &= ~PPCDBG_BITVAL(val);
2502 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2508 static void dump_slb(void)
2513 printf("SLB contents of cpu %x\n", smp_processor_id());
2515 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2516 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2517 printf("%02d %016lx ", i, tmp);
2519 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2520 printf("%016lx\n", tmp);
2524 static void dump_stab(void)
2527 unsigned long *tmp = (unsigned long *)get_paca()->xStab_data.virt;
2529 printf("Segment table contents of cpu %x\n", smp_processor_id());
2531 for (i = 0; i < PAGE_SIZE/16; i++) {
2538 printf("%03d %016lx ", i, a);
2539 printf("%016lx\n", b);
2544 void xmon_init(void)
2547 __debugger_ipi = xmon_ipi;
2548 __debugger_bpt = xmon_bpt;
2549 __debugger_sstep = xmon_sstep;
2550 __debugger_iabr_match = xmon_iabr_match;
2551 __debugger_dabr_match = xmon_dabr_match;
2552 __debugger_fault_handler = xmon_fault_handler;
2555 void dump_segments(void)
2557 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)