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 static unsigned long in_xmon = 0;
49 static unsigned long adrs;
51 static unsigned long ndump = 64;
52 static unsigned long nidump = 16;
53 static unsigned long ncsum = 4096;
55 static char tmpstr[128];
57 #define JMP_BUF_LEN (184/sizeof(long))
58 static long bus_error_jmp[JMP_BUF_LEN];
59 static int catch_memory_errors;
60 static long *xmon_fault_jmp[NR_CPUS];
61 #define setjmp xmon_setjmp
62 #define longjmp xmon_longjmp
64 /* Breakpoint stuff */
66 unsigned long address;
67 unsigned int instr[2];
73 /* Bits in bpt.enabled */
74 #define BP_IABR_TE 1 /* IABR translation enabled */
80 static struct bpt bpts[NBPTS];
81 static struct bpt dabr;
82 static struct bpt *iabr;
83 static unsigned bpinstr = 0x7fe00008; /* trap */
85 #define BP_NUM(bp) ((bp) - bpts + 1)
87 /* Bits in SRR1 that are copied from MSR */
88 #define MSR_MASK 0xffffffff87c0ffff
91 static int cmds(struct pt_regs *);
92 static int mread(unsigned long, void *, int);
93 static int mwrite(unsigned long, void *, int);
94 static int handle_fault(struct pt_regs *);
95 static void byterev(unsigned char *, int);
96 static void memex(void);
97 static int bsesc(void);
98 static void dump(void);
99 static void prdump(unsigned long, long);
100 static int ppc_inst_dump(unsigned long, long, int);
101 void print_address(unsigned long);
102 static void backtrace(struct pt_regs *);
103 static void excprint(struct pt_regs *);
104 static void prregs(struct pt_regs *);
105 static void memops(int);
106 static void memlocate(void);
107 static void memzcan(void);
108 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
110 int scanhex(unsigned long *valp);
111 static void scannl(void);
112 static int hexdigit(int);
113 void getstring(char *, int);
114 static void flush_input(void);
115 static int inchar(void);
116 static void take_input(char *);
117 static unsigned long read_spr(int);
118 static void write_spr(int, unsigned long);
119 static void super_regs(void);
120 static void remove_bpts(void);
121 static void insert_bpts(void);
122 static void remove_cpu_bpts(void);
123 static void insert_cpu_bpts(void);
124 static struct bpt *at_breakpoint(unsigned long pc);
125 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
126 static int do_step(struct pt_regs *);
127 static void bpt_cmds(void);
128 static void cacheflush(void);
129 static int cpu_cmd(void);
130 static void csum(void);
131 static void bootcmds(void);
132 void dump_segments(void);
133 static void symbol_lookup(void);
134 static int emulate_step(struct pt_regs *regs, unsigned int instr);
135 static void xmon_print_symbol(unsigned long address, const char *mid,
137 static const char *getvecname(unsigned long vec);
139 static void debug_trace(void);
141 extern int print_insn_powerpc(unsigned long, unsigned long, int);
142 extern void printf(const char *fmt, ...);
143 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
144 extern int xmon_putc(int c, void *f);
145 extern int putchar(int ch);
146 extern int xmon_read_poll(void);
147 extern int setjmp(long *);
148 extern void longjmp(long *, int);
149 extern unsigned long _ASR;
150 extern char SystemCall_common[];
152 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
154 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
156 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
157 || ('a' <= (c) && (c) <= 'f') \
158 || ('A' <= (c) && (c) <= 'F'))
159 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
160 || ('a' <= (c) && (c) <= 'z') \
161 || ('A' <= (c) && (c) <= 'Z'))
162 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
164 static char *help_string = "\
166 b show breakpoints\n\
167 bd set data breakpoint\n\
168 bi set instruction breakpoint\n\
169 bc clear breakpoint\n"
172 c print cpus stopped in xmon\n\
173 c# try to switch to cpu number h (in hex)\n"
178 di dump instructions\n\
179 df dump float values\n\
180 dd dump double values\n\
181 e print exception information\n\
183 la lookup symbol+offset of specified address\n\
184 ls lookup address of specified symbol\n\
185 m examine/change memory\n\
186 mm move a block of memory\n\
187 ms set a block of memory\n\
188 md compare two blocks of memory\n\
189 ml locate a block of memory\n\
190 mz zero a block of memory\n\
191 mi show information about memory allocation\n\
192 p show the task list\n\
195 S print special registers\n\
197 T Enable/Disable PPCDBG flags\n\
198 x exit monitor and recover\n\
199 X exit monitor and dont recover\n\
200 u dump segment table or SLB\n\
207 static struct pt_regs *xmon_regs;
209 extern inline void sync(void)
211 asm volatile("sync; isync");
214 /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
215 A PPC stack frame looks like this:
222 Parameter save area (SP+48)
223 TOC save area (SP+40)
224 link editor doubleword (SP+32)
225 compiler doubleword (SP+24)
230 Note that the LR (ret addr) may not be saved in the current frame if
231 no functions have been called from the current function.
235 * We don't allow single-stepping an mtmsrd that would clear
236 * MSR_RI, since that would make the exception unrecoverable.
237 * Since we need to single-step to proceed from a breakpoint,
238 * we don't allow putting a breakpoint on an mtmsrd instruction.
239 * Similarly we don't allow breakpoints on rfid instructions.
240 * These macros tell us if an instruction is a mtmsrd or rfid.
242 #define IS_MTMSRD(instr) (((instr) & 0xfc0007fe) == 0x7c000164)
243 #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024)
246 * Disable surveillance (the service processor watchdog function)
247 * while we are in xmon.
248 * XXX we should re-enable it when we leave. :)
250 #define SURVEILLANCE_TOKEN 9000
252 static inline void disable_surveillance(void)
254 #ifndef CONFIG_PPC_ISERIES
255 /* Since this can't be a module, args should end up below 4GB. */
256 static struct rtas_args args;
258 if (systemcfg->platform & PLATFORM_PSERIES) {
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)
271 args.rets = &args.args[3];
272 args.args[0] = SURVEILLANCE_TOKEN;
275 enter_rtas(__pa(&args));
281 static int xmon_speaker;
283 static void get_output_lock(void)
285 int me = smp_processor_id() + 0x100;
286 int last_speaker = 0, prev;
289 if (xmon_speaker == me)
292 if (xmon_speaker == 0) {
293 last_speaker = cmpxchg(&xmon_speaker, 0, me);
294 if (last_speaker == 0)
298 while (xmon_speaker == last_speaker) {
301 /* hostile takeover */
302 prev = cmpxchg(&xmon_speaker, last_speaker, me);
303 if (prev == last_speaker)
310 static void release_output_lock(void)
316 int xmon_core(struct pt_regs *regs, int fromipi)
321 long recurse_jmp[JMP_BUF_LEN];
322 unsigned long offset;
326 unsigned long timeout;
330 set_msrd(msr & ~MSR_EE); /* disable interrupts */
332 bp = in_breakpoint_table(regs->nip, &offset);
334 regs->nip = bp->address + offset;
335 atomic_dec(&bp->ref_count);
341 cpu = smp_processor_id();
342 if (cpu_isset(cpu, cpus_in_xmon)) {
345 printf("cpu 0x%x: Exception %lx %s in xmon, "
346 "returning to main loop\n",
347 cpu, regs->trap, getvecname(TRAP(regs)));
348 longjmp(xmon_fault_jmp[cpu], 1);
351 if (setjmp(recurse_jmp) != 0) {
352 if (!in_xmon || !xmon_gate) {
353 printf("xmon: WARNING: bad recursive fault "
354 "on cpu 0x%x\n", cpu);
357 secondary = !(xmon_taken && cpu == xmon_owner);
361 xmon_fault_jmp[cpu] = recurse_jmp;
362 cpu_set(cpu, cpus_in_xmon);
365 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
366 bp = at_breakpoint(regs->nip);
367 if (bp || (regs->msr & MSR_RI) == 0)
374 printf("cpu 0x%x stopped at breakpoint 0x%x (",
376 xmon_print_symbol(regs->nip, " ", ")\n");
378 if ((regs->msr & MSR_RI) == 0)
379 printf("WARNING: exception is not recoverable, "
381 release_output_lock();
386 while (secondary && !xmon_gate) {
390 secondary = test_and_set_bit(0, &in_xmon);
395 if (!secondary && !xmon_gate) {
396 /* we are the first cpu to come in */
397 /* interrupt other cpu(s) */
398 int ncpus = num_online_cpus();
403 smp_send_debugger_break(MSG_ALL_BUT_SELF);
404 /* wait for other cpus to come in */
405 for (timeout = 100000000; timeout != 0; --timeout)
406 if (cpus_weight(cpus_in_xmon) >= ncpus)
410 disable_surveillance();
411 /* for breakpoint or single step, print the current instr. */
412 if (bp || TRAP(regs) == 0xd00)
413 ppc_inst_dump(regs->nip, 1, 0);
414 printf("enter ? for help\n");
423 if (cpu == xmon_owner) {
424 if (!test_and_set_bit(0, &xmon_taken)) {
429 while (cpu == xmon_owner)
443 /* have switched to some other cpu */
448 cpu_clear(cpu, cpus_in_xmon);
449 xmon_fault_jmp[cpu] = NULL;
452 /* UP is simple... */
454 printf("Exception %lx %s in xmon, returning to main loop\n",
455 regs->trap, getvecname(TRAP(regs)));
456 longjmp(xmon_fault_jmp[0], 1);
458 if (setjmp(recurse_jmp) == 0) {
459 xmon_fault_jmp[0] = recurse_jmp;
463 bp = at_breakpoint(regs->nip);
465 printf("Stopped at breakpoint %x (", BP_NUM(bp));
466 xmon_print_symbol(regs->nip, " ", ")\n");
468 if ((regs->msr & MSR_RI) == 0)
469 printf("WARNING: exception is not recoverable, "
472 disable_surveillance();
473 /* for breakpoint or single step, print the current instr. */
474 if (bp || TRAP(regs) == 0xd00)
475 ppc_inst_dump(regs->nip, 1, 0);
476 printf("enter ? for help\n");
485 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
486 bp = at_breakpoint(regs->nip);
488 int stepped = emulate_step(regs, bp->instr[0]);
490 regs->nip = (unsigned long) &bp->instr[0];
491 atomic_inc(&bp->ref_count);
498 set_msrd(msr); /* restore interrupt enable */
503 int xmon(struct pt_regs *excp)
508 /* Ok, grab regs as they are now.
509 This won't do a particularily good job because the
510 prologue has already been executed.
511 ToDo: We could reach back into the callers save
512 area to do a better job of representing the
515 asm volatile ("std 0,0(%0)\n\
546 std 31,248(%0)" : : "b" (®s));
548 regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
549 regs.msr = get_msr();
550 regs.ctr = get_ctr();
551 regs.xer = get_xer();
556 return xmon_core(excp, 0);
559 int xmon_bpt(struct pt_regs *regs)
562 unsigned long offset;
564 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
567 /* Are we at the trap at bp->instr[1] for some bp? */
568 bp = in_breakpoint_table(regs->nip, &offset);
569 if (bp != NULL && offset == 4) {
570 regs->nip = bp->address + 4;
571 atomic_dec(&bp->ref_count);
575 /* Are we at a breakpoint? */
576 bp = at_breakpoint(regs->nip);
585 int xmon_sstep(struct pt_regs *regs)
593 int xmon_dabr_match(struct pt_regs *regs)
595 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
601 int xmon_iabr_match(struct pt_regs *regs)
603 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
611 int xmon_ipi(struct pt_regs *regs)
614 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
620 int xmon_fault_handler(struct pt_regs *regs)
623 unsigned long offset;
625 if (in_xmon && catch_memory_errors)
626 handle_fault(regs); /* doesn't return */
628 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
629 bp = in_breakpoint_table(regs->nip, &offset);
631 regs->nip = bp->address + offset;
632 atomic_dec(&bp->ref_count);
640 static struct bpt *at_breakpoint(unsigned long pc)
646 for (i = 0; i < NBPTS; ++i, ++bp)
647 if (bp->enabled && pc == bp->address)
652 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
656 off = nip - (unsigned long) bpts;
657 if (off >= sizeof(bpts))
659 off %= sizeof(struct bpt);
660 if (off != offsetof(struct bpt, instr[0])
661 && off != offsetof(struct bpt, instr[1]))
663 *offp = off - offsetof(struct bpt, instr[0]);
664 return (struct bpt *) (nip - off);
667 static struct bpt *new_breakpoint(unsigned long a)
672 bp = at_breakpoint(a);
676 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
677 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
679 bp->instr[1] = bpinstr;
680 store_inst(&bp->instr[1]);
685 printf("Sorry, no free breakpoints. Please clear one first.\n");
689 static void insert_bpts(void)
695 for (i = 0; i < NBPTS; ++i, ++bp) {
696 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
698 if (mread(bp->address, &bp->instr[0], 4) != 4) {
699 printf("Couldn't read instruction at %lx, "
700 "disabling breakpoint there\n", bp->address);
704 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
705 printf("Breakpoint at %lx is on an mtmsrd or rfid "
706 "instruction, disabling it\n", bp->address);
710 store_inst(&bp->instr[0]);
711 if (bp->enabled & BP_IABR)
713 if (mwrite(bp->address, &bpinstr, 4) != 4) {
714 printf("Couldn't write instruction at %lx, "
715 "disabling breakpoint there\n", bp->address);
716 bp->enabled &= ~BP_TRAP;
719 store_inst((void *)bp->address);
723 static void insert_cpu_bpts(void)
726 set_dabr(dabr.address | (dabr.enabled & 7));
727 if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
728 set_iabr(iabr->address
729 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
732 static void remove_bpts(void)
739 for (i = 0; i < NBPTS; ++i, ++bp) {
740 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
742 if (mread(bp->address, &instr, 4) == 4
744 && mwrite(bp->address, &bp->instr, 4) != 4)
745 printf("Couldn't remove breakpoint at %lx\n",
748 store_inst((void *)bp->address);
752 static void remove_cpu_bpts(void)
755 if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
759 static int branch_taken(unsigned int instr, struct pt_regs *regs)
761 unsigned int bo = (instr >> 21) & 0x1f;
765 /* decrement counter */
767 if (((bo >> 1) & 1) ^ (regs->ctr == 0))
770 if ((bo & 0x10) == 0) {
771 /* check bit from CR */
772 bi = (instr >> 16) & 0x1f;
773 if (((regs->ccr >> (31 - bi)) & 1) != ((bo >> 3) & 1))
780 * Emulate instructions that cause a transfer of control.
781 * Returns 1 if the step was emulated, 0 if not,
782 * or -1 if the instruction is one that should not be stepped,
783 * such as an rfid, or a mtmsrd that would clear MSR_RI.
785 static int emulate_step(struct pt_regs *regs, unsigned int instr)
787 unsigned int opcode, rd;
788 unsigned long int imm;
790 opcode = instr >> 26;
793 imm = (signed short)(instr & 0xfffc);
794 if ((instr & 2) == 0)
796 regs->nip += 4; /* XXX check 32-bit mode */
798 regs->link = regs->nip;
799 if (branch_taken(instr, regs))
803 regs->gpr[9] = regs->gpr[13];
804 regs->gpr[11] = regs->nip + 4;
805 regs->gpr[12] = regs->msr & MSR_MASK;
806 regs->gpr[13] = (unsigned long) get_paca();
807 regs->nip = (unsigned long) &SystemCall_common;
808 regs->msr = MSR_KERNEL;
811 imm = instr & 0x03fffffc;
812 if (imm & 0x02000000)
814 if ((instr & 2) == 0)
817 regs->link = regs->nip + 4;
821 switch (instr & 0x7fe) {
822 case 0x20: /* bclr */
823 case 0x420: /* bcctr */
824 imm = (instr & 0x400)? regs->ctr: regs->link;
825 regs->nip += 4; /* XXX check 32-bit mode */
827 regs->link = regs->nip;
828 if (branch_taken(instr, regs))
831 case 0x24: /* rfid, scary */
832 printf("Can't single-step an rfid instruction\n");
836 rd = (instr >> 21) & 0x1f;
837 switch (instr & 0x7fe) {
838 case 0xa6: /* mfmsr */
839 regs->gpr[rd] = regs->msr & MSR_MASK;
842 case 0x164: /* mtmsrd */
843 /* only MSR_EE and MSR_RI get changed if bit 15 set */
844 /* mtmsrd doesn't change MSR_HV and MSR_ME */
845 imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
846 imm = (regs->msr & MSR_MASK & ~imm)
847 | (regs->gpr[rd] & imm);
848 if ((imm & MSR_RI) == 0) {
849 printf("Can't step an instruction that would "
861 /* Command interpreting routine */
862 static char *last_cmd;
865 cmds(struct pt_regs *excp)
873 printf("%x:", smp_processor_id());
874 #endif /* CONFIG_SMP */
881 if (last_cmd == NULL)
883 take_input(last_cmd);
917 prregs(excp); /* print regs */
965 printf("Unrecognized command: ");
967 if (' ' < cmd && cmd <= '~')
970 printf("\\x%x", cmd);
972 } while (cmd != '\n');
973 printf(" (type ? for help)\n");
980 * Step a single instruction.
981 * Some instructions we emulate, others we execute with MSR_SE set.
983 static int do_step(struct pt_regs *regs)
988 /* check we are in 64-bit kernel mode, translation enabled */
989 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
990 if (mread(regs->nip, &instr, 4) == 4) {
991 stepped = emulate_step(regs, instr);
995 regs->trap = 0xd00 | (regs->trap & 1);
996 printf("stepped to ");
997 xmon_print_symbol(regs->nip, " ", "\n");
998 ppc_inst_dump(regs->nip, 1, 0);
1003 regs->msr |= MSR_SE;
1007 static void bootcmds(void)
1013 ppc_md.restart(NULL);
1014 else if (cmd == 'h')
1016 else if (cmd == 'p')
1020 static int cpu_cmd(void)
1027 if (!scanhex(&cpu)) {
1028 /* print cpus waiting or in xmon */
1029 printf("cpus stopped:");
1031 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
1032 if (cpu_isset(cpu, cpus_in_xmon)) {
1038 printf("-%x", cpu - 1);
1043 printf("-%x", NR_CPUS - 1);
1047 /* try to switch to cpu specified */
1048 if (!cpu_isset(cpu, cpus_in_xmon)) {
1049 printf("cpu 0x%x isn't in xmon\n", cpu);
1056 while (!xmon_taken) {
1057 if (--timeout == 0) {
1058 if (test_and_set_bit(0, &xmon_taken))
1060 /* take control back */
1062 xmon_owner = smp_processor_id();
1063 printf("cpu %u didn't take control\n", cpu);
1071 #endif /* CONFIG_SMP */
1074 static unsigned short fcstab[256] = {
1075 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1076 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1077 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1078 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1079 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1080 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1081 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1082 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1083 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1084 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1085 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1086 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1087 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1088 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1089 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1090 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1091 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1092 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1093 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1094 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1095 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1096 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1097 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1098 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1099 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1100 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1101 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1102 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1103 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1104 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1105 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1106 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1109 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1118 if (!scanhex(&adrs))
1120 if (!scanhex(&ncsum))
1123 for (i = 0; i < ncsum; ++i) {
1124 if (mread(adrs+i, &v, 1) == 0) {
1125 printf("csum stopped at %x\n", adrs+i);
1130 printf("%x\n", fcs);
1134 * Check if this is a suitable place to put a breakpoint.
1136 static long check_bp_loc(unsigned long addr)
1141 if (addr < KERNELBASE) {
1142 printf("Breakpoints may only be placed at kernel addresses\n");
1145 if (!mread(addr, &instr, sizeof(instr))) {
1146 printf("Can't read instruction at address %lx\n", addr);
1149 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1150 printf("Breakpoints may not be placed on mtmsrd or rfid "
1157 static char *breakpoint_help_string =
1158 "Breakpoint command usage:\n"
1159 "b show breakpoints\n"
1160 "b <addr> [cnt] set breakpoint at given instr addr\n"
1161 "bc clear all breakpoints\n"
1162 "bc <n/addr> clear breakpoint number n or at addr\n"
1163 "bi <addr> [cnt] set hardware instr breakpoint (broken?)\n"
1164 "bd <addr> [cnt] set hardware data breakpoint (broken?)\n"
1174 const char badaddr[] = "Only kernel addresses are permitted "
1175 "for breakpoints\n";
1179 case 'd': /* bd - hardware data breakpoint */
1184 else if (cmd == 'w')
1190 if (scanhex(&dabr.address)) {
1191 if (dabr.address < KERNELBASE) {
1196 dabr.enabled = mode | BP_DABR;
1200 case 'i': /* bi - hardware instr breakpoint */
1201 if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
1202 printf("Hardware instruction breakpoint "
1203 "not supported on this cpu\n");
1207 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1212 if (!check_bp_loc(a))
1214 bp = new_breakpoint(a);
1216 bp->enabled |= BP_IABR | BP_IABR_TE;
1223 /* clear all breakpoints */
1224 for (i = 0; i < NBPTS; ++i)
1225 bpts[i].enabled = 0;
1228 printf("All breakpoints cleared\n");
1232 if (a <= NBPTS && a >= 1) {
1233 /* assume a breakpoint number */
1234 bp = &bpts[a-1]; /* bp nums are 1 based */
1236 /* assume a breakpoint address */
1237 bp = at_breakpoint(a);
1239 printf("No breakpoint at %x\n", a);
1244 printf("Cleared breakpoint %x (", BP_NUM(bp));
1245 xmon_print_symbol(bp->address, " ", ")\n");
1253 printf(breakpoint_help_string);
1258 /* print all breakpoints */
1259 printf(" type address\n");
1261 printf(" data %.16lx [", dabr.address);
1262 if (dabr.enabled & 1)
1264 if (dabr.enabled & 2)
1268 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1271 printf("%2x %s ", BP_NUM(bp),
1272 (bp->enabled & BP_IABR)? "inst": "trap");
1273 xmon_print_symbol(bp->address, " ", "\n");
1278 if (!check_bp_loc(a))
1280 bp = new_breakpoint(a);
1282 bp->enabled |= BP_TRAP;
1287 /* Very cheap human name for vector lookup. */
1289 const char *getvecname(unsigned long vec)
1294 case 0x100: ret = "(System Reset)"; break;
1295 case 0x200: ret = "(Machine Check)"; break;
1296 case 0x300: ret = "(Data Access)"; break;
1297 case 0x380: ret = "(Data SLB Access)"; break;
1298 case 0x400: ret = "(Instruction Access)"; break;
1299 case 0x480: ret = "(Instruction SLB Access)"; break;
1300 case 0x500: ret = "(Hardware Interrupt)"; break;
1301 case 0x600: ret = "(Alignment)"; break;
1302 case 0x700: ret = "(Program Check)"; break;
1303 case 0x800: ret = "(FPU Unavailable)"; break;
1304 case 0x900: ret = "(Decrementer)"; break;
1305 case 0xc00: ret = "(System Call)"; break;
1306 case 0xd00: ret = "(Single Step)"; break;
1307 case 0xf00: ret = "(Performance Monitor)"; break;
1308 case 0xf20: ret = "(Altivec Unavailable)"; break;
1309 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1315 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1316 unsigned long *endp)
1318 unsigned long size, offset;
1322 *startp = *endp = 0;
1325 if (setjmp(bus_error_jmp) == 0) {
1326 catch_memory_errors = 1;
1328 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1330 *startp = pc - offset;
1331 *endp = pc - offset + size;
1335 catch_memory_errors = 0;
1338 static int xmon_depth_to_print = 64;
1340 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1344 unsigned long newsp;
1345 unsigned long marker;
1347 struct pt_regs regs;
1350 if (sp < PAGE_OFFSET) {
1352 printf("SP (%lx) is in userspace\n", sp);
1356 if (!mread(sp + 16, &ip, sizeof(unsigned long))
1357 || !mread(sp, &newsp, sizeof(unsigned long))) {
1358 printf("Couldn't read stack frame at %lx\n", sp);
1363 * For the first stack frame, try to work out if
1364 * LR and/or the saved LR value in the bottommost
1365 * stack frame are valid.
1367 if ((pc | lr) != 0) {
1368 unsigned long fnstart, fnend;
1369 unsigned long nextip;
1372 get_function_bounds(pc, &fnstart, &fnend);
1375 mread(newsp + 16, &nextip,
1376 sizeof(unsigned long));
1378 if (lr < PAGE_OFFSET
1379 || (fnstart <= lr && lr < fnend))
1381 } else if (lr == nextip) {
1383 } else if (lr >= PAGE_OFFSET
1384 && !(fnstart <= lr && lr < fnend)) {
1385 printf("[link register ] ");
1386 xmon_print_symbol(lr, " ", "\n");
1389 printf("[%.16lx] ", sp);
1390 xmon_print_symbol(ip, " ", " (unreliable)\n");
1395 printf("[%.16lx] ", sp);
1396 xmon_print_symbol(ip, " ", "\n");
1399 /* Look for "regshere" marker to see if this is
1400 an exception frame. */
1401 if (mread(sp + 0x60, &marker, sizeof(unsigned long))
1402 && marker == 0x7265677368657265ul) {
1403 if (mread(sp + 0x70, ®s, sizeof(regs))
1405 printf("Couldn't read registers at %lx\n",
1409 printf("--- Exception: %lx %s at ", regs.trap,
1410 getvecname(TRAP(®s)));
1413 xmon_print_symbol(pc, " ", "\n");
1420 } while (count++ < xmon_depth_to_print);
1423 static void backtrace(struct pt_regs *excp)
1428 xmon_show_stack(sp, 0, 0);
1430 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1434 void excprint(struct pt_regs *fp)
1439 printf("cpu 0x%x: ", smp_processor_id());
1440 #endif /* CONFIG_SMP */
1443 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1445 xmon_print_symbol(fp->nip, ": ", "\n");
1447 printf(" lr: ", fp->link);
1448 xmon_print_symbol(fp->link, ": ", "\n");
1450 printf(" sp: %lx\n", fp->gpr[1]);
1451 printf(" msr: %lx\n", fp->msr);
1453 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1454 printf(" dar: %lx\n", fp->dar);
1456 printf(" dsisr: %lx\n", fp->dsisr);
1459 printf(" current = 0x%lx\n", current);
1460 printf(" paca = 0x%lx\n", get_paca());
1462 printf(" pid = %ld, comm = %s\n",
1463 current->pid, current->comm);
1467 void prregs(struct pt_regs *fp)
1471 struct pt_regs regs;
1473 if (scanhex(&base)) {
1474 if (setjmp(bus_error_jmp) == 0) {
1475 catch_memory_errors = 1;
1477 regs = *(struct pt_regs *)base;
1481 catch_memory_errors = 0;
1482 printf("*** Error reading registers from %.16lx\n",
1486 catch_memory_errors = 0;
1490 if (FULL_REGS(fp)) {
1491 for (n = 0; n < 16; ++n)
1492 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1493 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1495 for (n = 0; n < 7; ++n)
1496 printf("R%.2ld = %.16lx R%.2ld = %.16lx\n",
1497 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1500 xmon_print_symbol(fp->nip, " ", "\n");
1502 xmon_print_symbol(fp->link, " ", "\n");
1503 printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr);
1504 printf("ctr = %.16lx xer = %.16lx trap = %8lx\n",
1505 fp->ctr, fp->xer, fp->trap);
1508 void cacheflush(void)
1511 unsigned long nflush;
1516 scanhex((void *)&adrs);
1521 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1522 if (setjmp(bus_error_jmp) == 0) {
1523 catch_memory_errors = 1;
1527 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1528 cflush((void *) adrs);
1530 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1531 cinval((void *) adrs);
1534 /* wait a little while to see if we get a machine check */
1537 catch_memory_errors = 0;
1543 unsigned int instrs[2];
1544 unsigned long (*code)(void);
1545 unsigned long opd[3];
1546 unsigned long ret = -1UL;
1548 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1549 instrs[1] = 0x4e800020;
1550 opd[0] = (unsigned long)instrs;
1554 store_inst(instrs+1);
1555 code = (unsigned long (*)(void)) opd;
1563 write_spr(int n, unsigned long val)
1565 unsigned int instrs[2];
1566 unsigned long (*code)(unsigned long);
1567 unsigned long opd[3];
1569 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1570 instrs[1] = 0x4e800020;
1571 opd[0] = (unsigned long)instrs;
1575 store_inst(instrs+1);
1576 code = (unsigned long (*)(unsigned long)) opd;
1581 static unsigned long regno;
1582 extern char exc_prolog;
1583 extern char dec_exc;
1590 #ifdef CONFIG_PPC_ISERIES
1591 struct paca_struct *ptrPaca = NULL;
1592 struct ItLpPaca *ptrLpPaca = NULL;
1593 struct ItLpRegSave *ptrLpRegSave = NULL;
1598 unsigned long sp, toc;
1599 asm("mr %0,1" : "=r" (sp) :);
1600 asm("mr %0,2" : "=r" (toc) :);
1602 printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
1603 printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
1604 printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2());
1605 printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
1606 printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
1607 printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
1608 #ifdef CONFIG_PPC_ISERIES
1609 // Dump out relevant Paca data areas.
1611 ptrPaca = get_paca();
1613 printf(" Local Processor Control Area (LpPaca): \n");
1614 ptrLpPaca = ptrPaca->xLpPacaPtr;
1615 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1616 ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
1617 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1618 ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
1619 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
1621 printf(" Local Processor Register Save Area (LpRegSave): \n");
1622 ptrLpRegSave = ptrPaca->xLpRegSavePtr;
1623 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1624 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1625 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1626 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1627 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1628 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1637 val = read_spr(regno);
1639 write_spr(regno, val);
1642 printf("spr %lx = %lx\n", regno, read_spr(regno));
1654 * Stuff for reading and writing memory safely
1657 mread(unsigned long adrs, void *buf, int size)
1663 if (setjmp(bus_error_jmp) == 0) {
1664 catch_memory_errors = 1;
1670 *(short *)q = *(short *)p;
1673 *(int *)q = *(int *)p;
1676 *(long *)q = *(long *)p;
1679 for( ; n < size; ++n) {
1685 /* wait a little while to see if we get a machine check */
1689 catch_memory_errors = 0;
1694 mwrite(unsigned long adrs, void *buf, int size)
1700 if (setjmp(bus_error_jmp) == 0) {
1701 catch_memory_errors = 1;
1707 *(short *)p = *(short *)q;
1710 *(int *)p = *(int *)q;
1713 *(long *)p = *(long *)q;
1716 for ( ; n < size; ++n) {
1722 /* wait a little while to see if we get a machine check */
1726 printf("*** Error writing address %x\n", adrs + n);
1728 catch_memory_errors = 0;
1732 static int fault_type;
1733 static char *fault_chars[] = { "--", "**", "##" };
1736 handle_fault(struct pt_regs *regs)
1738 switch (TRAP(regs)) {
1750 longjmp(bus_error_jmp, 1);
1755 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1758 byterev(unsigned char *val, int size)
1764 SWAP(val[0], val[1], t);
1767 SWAP(val[0], val[3], t);
1768 SWAP(val[1], val[2], t);
1770 case 8: /* is there really any use for this? */
1771 SWAP(val[0], val[7], t);
1772 SWAP(val[1], val[6], t);
1773 SWAP(val[2], val[5], t);
1774 SWAP(val[3], val[4], t);
1782 static char *memex_help_string =
1783 "Memory examine command usage:\n"
1784 "m [addr] [flags] examine/change memory\n"
1785 " addr is optional. will start where left off.\n"
1786 " flags may include chars from this set:\n"
1787 " b modify by bytes (default)\n"
1788 " w modify by words (2 byte)\n"
1789 " l modify by longs (4 byte)\n"
1790 " d modify by doubleword (8 byte)\n"
1791 " r toggle reverse byte order mode\n"
1792 " n do not read memory (for i/o spaces)\n"
1793 " . ok to read (default)\n"
1794 "NOTE: flags are saved as defaults\n"
1797 static char *memex_subcmd_help_string =
1798 "Memory examine subcommands:\n"
1799 " hexval write this val to current location\n"
1800 " 'string' write chars from string to this location\n"
1801 " ' increment address\n"
1802 " ^ decrement address\n"
1803 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1804 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1805 " ` clear no-read flag\n"
1806 " ; stay at this addr\n"
1807 " v change to byte mode\n"
1808 " w change to word (2 byte) mode\n"
1809 " l change to long (4 byte) mode\n"
1810 " u change to doubleword (8 byte) mode\n"
1811 " m addr change current addr\n"
1812 " n toggle no-read flag\n"
1813 " r toggle byte reverse flag\n"
1814 " < count back up count bytes\n"
1815 " > count skip forward count bytes\n"
1816 " x exit this mode\n"
1822 int cmd, inc, i, nslash;
1824 unsigned char val[16];
1826 scanhex((void *)&adrs);
1829 printf(memex_help_string);
1835 while ((cmd = skipbl()) != '\n') {
1837 case 'b': size = 1; break;
1838 case 'w': size = 2; break;
1839 case 'l': size = 4; break;
1840 case 'd': size = 8; break;
1841 case 'r': brev = !brev; break;
1842 case 'n': mnoread = 1; break;
1843 case '.': mnoread = 0; break;
1852 n = mread(adrs, val, size);
1853 printf("%.16x%c", adrs, brev? 'r': ' ');
1858 for (i = 0; i < n; ++i)
1859 printf("%.2x", val[i]);
1860 for (; i < size; ++i)
1861 printf("%s", fault_chars[fault_type]);
1868 for (i = 0; i < size; ++i)
1869 val[i] = n >> (i * 8);
1872 mwrite(adrs, val, size);
1885 else if( n == '\'' )
1887 for (i = 0; i < size; ++i)
1888 val[i] = n >> (i * 8);
1891 mwrite(adrs, val, size);
1928 adrs -= 1 << nslash;
1932 adrs += 1 << nslash;
1936 adrs += 1 << -nslash;
1940 adrs -= 1 << -nslash;
1943 scanhex((void *)&adrs);
1962 printf(memex_subcmd_help_string);
1977 case 'n': c = '\n'; break;
1978 case 'r': c = '\r'; break;
1979 case 'b': c = '\b'; break;
1980 case 't': c = '\t'; break;
1985 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1986 || ('a' <= (c) && (c) <= 'f') \
1987 || ('A' <= (c) && (c) <= 'F'))
1994 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1996 scanhex((void *)&adrs);
2003 adrs += ppc_inst_dump(adrs, nidump, 1);
2009 prdump(adrs, ndump);
2016 prdump(unsigned long adrs, long ndump)
2018 long n, m, c, r, nr;
2019 unsigned char temp[16];
2021 for (n = ndump; n > 0;) {
2022 printf("%.16lx", adrs);
2025 nr = mread(adrs, temp, r);
2027 for (m = 0; m < r; ++m) {
2028 if ((m & 7) == 0 && m > 0)
2031 printf("%.2x", temp[m]);
2033 printf("%s", fault_chars[fault_type]);
2040 for (m = 0; m < r; ++m) {
2043 putchar(' ' <= c && c <= '~'? c: '.');
2057 ppc_inst_dump(unsigned long adr, long count, int praddr)
2060 unsigned long first_adr;
2061 unsigned long inst, last_inst;
2062 unsigned char val[4];
2065 for (first_adr = adr; count > 0; --count, adr += 4) {
2066 nr = mread(adr, val, 4);
2069 const char *x = fault_chars[fault_type];
2070 printf("%.16lx %s%s%s%s\n", adr, x, x, x, x);
2074 inst = GETWORD(val);
2075 if (adr > first_adr && inst == last_inst) {
2085 printf("%.16lx %.8x", adr, inst);
2087 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2090 return adr - first_adr;
2094 print_address(unsigned long addr)
2096 xmon_print_symbol(addr, "\t# ", "");
2101 * Memory operations - move, set, print differences
2103 static unsigned long mdest; /* destination address */
2104 static unsigned long msrc; /* source address */
2105 static unsigned long mval; /* byte value to set memory to */
2106 static unsigned long mcount; /* # bytes to affect */
2107 static unsigned long mdiffs; /* max # differences to print */
2112 scanhex((void *)&mdest);
2113 if( termch != '\n' )
2115 scanhex((void *)(cmd == 's'? &mval: &msrc));
2116 if( termch != '\n' )
2118 scanhex((void *)&mcount);
2121 memmove((void *)mdest, (void *)msrc, mcount);
2124 memset((void *)mdest, mval, mcount);
2127 if( termch != '\n' )
2129 scanhex((void *)&mdiffs);
2130 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2136 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2141 for( n = nb; n > 0; --n )
2142 if( *p1++ != *p2++ )
2143 if( ++prt <= maxpr )
2144 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2145 p1[-1], p2 - 1, p2[-1]);
2147 printf("Total of %d differences\n", prt);
2150 static unsigned mend;
2151 static unsigned mask;
2157 unsigned char val[4];
2160 scanhex((void *)&mdest);
2161 if (termch != '\n') {
2163 scanhex((void *)&mend);
2164 if (termch != '\n') {
2166 scanhex((void *)&mval);
2168 if (termch != '\n') termch = 0;
2169 scanhex((void *)&mask);
2173 for (a = mdest; a < mend; a += 4) {
2174 if (mread(a, val, 4) == 4
2175 && ((GETWORD(val) ^ mval) & mask) == 0) {
2176 printf("%.16x: %.16x\n", a, GETWORD(val));
2183 static unsigned long mskip = 0x1000;
2184 static unsigned long mlim = 0xffffffff;
2194 if (termch != '\n') termch = 0;
2196 if (termch != '\n') termch = 0;
2199 for (a = mdest; a < mlim; a += mskip) {
2200 ok = mread(a, &v, 1);
2202 printf("%.8x .. ", a);
2204 } else if (!ok && ook)
2205 printf("%.8x\n", a - mskip);
2211 printf("%.8x\n", a - mskip);
2214 /* Input scanning routines */
2225 while( c == ' ' || c == '\t' )
2231 static char *regnames[N_PTREGS] = {
2232 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2233 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2234 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2235 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2236 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",
2237 "trap", "dar", "dsisr", "res"
2249 /* parse register name */
2253 for (i = 0; i < sizeof(regname) - 1; ++i) {
2262 for (i = 0; i < N_PTREGS; ++i) {
2263 if (strcmp(regnames[i], regname) == 0) {
2264 if (xmon_regs == NULL) {
2265 printf("regs not available\n");
2268 *vp = ((unsigned long *)xmon_regs)[i];
2272 printf("invalid register name '%%%s'\n", regname);
2276 /* skip leading "0x" if any */
2290 } else if (c == '$') {
2292 for (i=0; i<63; i++) {
2301 *vp = kallsyms_lookup_name(tmpstr);
2303 printf("unknown symbol '%s'\n", tmpstr);
2339 if( '0' <= c && c <= '9' )
2341 if( 'A' <= c && c <= 'F' )
2342 return c - ('A' - 10);
2343 if( 'a' <= c && c <= 'f' )
2344 return c - ('a' - 10);
2349 getstring(char *s, int size)
2360 } while( c != ' ' && c != '\t' && c != '\n' );
2365 static char line[256];
2366 static char *lineptr;
2377 if (lineptr == NULL || *lineptr == 0) {
2378 if (fgets(line, sizeof(line), stdin) == NULL) {
2398 int type = inchar();
2400 static char tmp[64];
2405 xmon_print_symbol(addr, ": ", "\n");
2410 if (setjmp(bus_error_jmp) == 0) {
2411 catch_memory_errors = 1;
2413 addr = kallsyms_lookup_name(tmp);
2415 printf("%s: %lx\n", tmp, addr);
2417 printf("Symbol '%s' not found.\n", tmp);
2420 catch_memory_errors = 0;
2427 /* Print an address in numeric and symbolic form (if possible) */
2428 static void xmon_print_symbol(unsigned long address, const char *mid,
2432 const char *name = NULL;
2433 unsigned long offset, size;
2435 printf("%.16lx", address);
2436 if (setjmp(bus_error_jmp) == 0) {
2437 catch_memory_errors = 1;
2439 name = kallsyms_lookup(address, &size, &offset, &modname,
2442 /* wait a little while to see if we get a machine check */
2446 catch_memory_errors = 0;
2449 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2451 printf(" [%s]", modname);
2453 printf("%s", after);
2456 static void debug_trace(void)
2458 unsigned long val, cmd, on;
2462 /* show current state */
2464 printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
2465 for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
2466 on = PPCDBG_BITVAL(i) & naca->debug_switch;
2467 printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : "");
2468 if (((i+1) % 3) == 0)
2474 while (cmd != '\n') {
2475 on = 1; /* default if no sign given */
2476 while (cmd == '+' || cmd == '-') {
2479 if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */
2480 naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
2481 printf("Setting all values to %s...\n", on ? "on" : "off");
2482 if (cmd == '\n') return;
2483 else cmd = skipbl();
2488 termch = cmd; /* not +/- ... let scanhex see it */
2489 scanhex((void *)&val);
2491 printf("Value %x out of range:\n", val);
2495 naca->debug_switch |= PPCDBG_BITVAL(val);
2496 printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2498 naca->debug_switch &= ~PPCDBG_BITVAL(val);
2499 printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
2505 static void dump_slb(void)
2510 printf("SLB contents of cpu %x\n", smp_processor_id());
2512 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2513 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2514 printf("%02d %016lx ", i, tmp);
2516 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2517 printf("%016lx\n", tmp);
2521 static void dump_stab(void)
2524 unsigned long *tmp = (unsigned long *)get_paca()->xStab_data.virt;
2526 printf("Segment table contents of cpu %x\n", smp_processor_id());
2528 for (i = 0; i < PAGE_SIZE/16; i++) {
2535 printf("%03d %016lx ", i, a);
2536 printf("%016lx\n", b);
2541 void xmon_init(void)
2544 __debugger_ipi = xmon_ipi;
2545 __debugger_bpt = xmon_bpt;
2546 __debugger_sstep = xmon_sstep;
2547 __debugger_iabr_match = xmon_iabr_match;
2548 __debugger_dabr_match = xmon_dabr_match;
2549 __debugger_fault_handler = xmon_fault_handler;
2552 void dump_segments(void)
2554 if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)