Merge branches 'pm-opp', 'pm-cpufreq' and 'pm-tools'
[linux-2.6-block.git] / arch / powerpc / xmon / xmon.c
CommitLineData
1da177e4
LT
1/*
2 * Routines providing a simple monitor for use on the PowerMac.
3 *
fca5dcd4 4 * Copyright (C) 1996-2005 Paul Mackerras.
47679283
ME
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
1da177e4
LT
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
1da177e4
LT
13#include <linux/errno.h>
14#include <linux/sched.h>
15#include <linux/smp.h>
16#include <linux/mm.h>
17#include <linux/reboot.h>
18#include <linux/delay.h>
19#include <linux/kallsyms.h>
ca5dd395 20#include <linux/kmsg_dump.h>
1da177e4 21#include <linux/cpumask.h>
4b16f8e2 22#include <linux/export.h>
fca5dcd4 23#include <linux/sysrq.h>
4694ca02 24#include <linux/interrupt.h>
7d12e780 25#include <linux/irq.h>
73c9ceab 26#include <linux/bug.h>
a71d64b4 27#include <linux/nmi.h>
1da177e4
LT
28
29#include <asm/ptrace.h>
30#include <asm/string.h>
31#include <asm/prom.h>
32#include <asm/machdep.h>
f78541dc 33#include <asm/xmon.h>
1da177e4
LT
34#include <asm/processor.h>
35#include <asm/pgtable.h>
36#include <asm/mmu.h>
37#include <asm/mmu_context.h>
1da177e4
LT
38#include <asm/cputable.h>
39#include <asm/rtas.h>
40#include <asm/sstep.h>
f583ffce 41#include <asm/irq_regs.h>
ff8a8f25
ME
42#include <asm/spu.h>
43#include <asm/spu_priv1.h>
c3b75bd7 44#include <asm/setjmp.h>
322b4394 45#include <asm/reg.h>
ae3a197e 46#include <asm/debug.h>
9422de3e 47#include <asm/hw_breakpoint.h>
f78541dc
PM
48
49#ifdef CONFIG_PPC64
1da177e4 50#include <asm/hvcall.h>
f78541dc
PM
51#include <asm/paca.h>
52#endif
1da177e4
LT
53
54#include "nonstdio.h"
e0426047 55#include "dis-asm.h"
1da177e4 56
1da177e4 57#ifdef CONFIG_SMP
1c8950ff 58static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
1da177e4
LT
59static unsigned long xmon_taken = 1;
60static int xmon_owner;
61static int xmon_gate;
ddadb6b8
ME
62#else
63#define xmon_owner 0
1da177e4
LT
64#endif /* CONFIG_SMP */
65
5be3492f 66static unsigned long in_xmon __read_mostly = 0;
1da177e4
LT
67
68static unsigned long adrs;
69static int size = 1;
70#define MAX_DUMP (128 * 1024)
71static unsigned long ndump = 64;
72static unsigned long nidump = 16;
73static unsigned long ncsum = 4096;
74static int termch;
75static char tmpstr[128];
76
1da177e4
LT
77static long bus_error_jmp[JMP_BUF_LEN];
78static int catch_memory_errors;
79static long *xmon_fault_jmp[NR_CPUS];
1da177e4
LT
80
81/* Breakpoint stuff */
82struct bpt {
83 unsigned long address;
84 unsigned int instr[2];
85 atomic_t ref_count;
86 int enabled;
87 unsigned long pad;
88};
89
90/* Bits in bpt.enabled */
91#define BP_IABR_TE 1 /* IABR translation enabled */
92#define BP_IABR 2
93#define BP_TRAP 8
94#define BP_DABR 0x10
95
96#define NBPTS 256
97static struct bpt bpts[NBPTS];
98static struct bpt dabr;
99static struct bpt *iabr;
100static unsigned bpinstr = 0x7fe00008; /* trap */
101
102#define BP_NUM(bp) ((bp) - bpts + 1)
103
104/* Prototypes */
105static int cmds(struct pt_regs *);
106static int mread(unsigned long, void *, int);
107static int mwrite(unsigned long, void *, int);
108static int handle_fault(struct pt_regs *);
109static void byterev(unsigned char *, int);
110static void memex(void);
111static int bsesc(void);
112static void dump(void);
113static void prdump(unsigned long, long);
114static int ppc_inst_dump(unsigned long, long, int);
f312deb4 115static void dump_log_buf(void);
1da177e4
LT
116static void backtrace(struct pt_regs *);
117static void excprint(struct pt_regs *);
118static void prregs(struct pt_regs *);
119static void memops(int);
120static void memlocate(void);
121static void memzcan(void);
122static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
123int skipbl(void);
124int scanhex(unsigned long *valp);
125static void scannl(void);
126static int hexdigit(int);
127void getstring(char *, int);
128static void flush_input(void);
129static int inchar(void);
130static void take_input(char *);
131static unsigned long read_spr(int);
132static void write_spr(int, unsigned long);
133static void super_regs(void);
134static void remove_bpts(void);
135static void insert_bpts(void);
136static void remove_cpu_bpts(void);
137static void insert_cpu_bpts(void);
138static struct bpt *at_breakpoint(unsigned long pc);
139static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
140static int do_step(struct pt_regs *);
141static void bpt_cmds(void);
142static void cacheflush(void);
143static int cpu_cmd(void);
144static void csum(void);
145static void bootcmds(void);
f78541dc 146static void proccall(void);
1da177e4
LT
147void dump_segments(void);
148static void symbol_lookup(void);
26c8af5f
OH
149static void xmon_show_stack(unsigned long sp, unsigned long lr,
150 unsigned long pc);
1da177e4
LT
151static void xmon_print_symbol(unsigned long address, const char *mid,
152 const char *after);
153static const char *getvecname(unsigned long vec);
154
ff8a8f25
ME
155static int do_spu_cmd(void);
156
5a8a1a28
BH
157#ifdef CONFIG_44x
158static void dump_tlb_44x(void);
159#endif
03247157
BH
160#ifdef CONFIG_PPC_BOOK3E
161static void dump_tlb_book3e(void);
162#endif
5a8a1a28 163
9f1067c2 164static int xmon_no_auto_backtrace;
26c8af5f 165
f78541dc
PM
166extern void xmon_enter(void);
167extern void xmon_leave(void);
168
f78541dc
PM
169#ifdef CONFIG_PPC64
170#define REG "%.16lx"
f78541dc
PM
171#else
172#define REG "%.8lx"
f78541dc 173#endif
1da177e4 174
72eceef6
PB
175#ifdef __LITTLE_ENDIAN__
176#define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
177#else
1da177e4 178#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
72eceef6 179#endif
1da177e4
LT
180
181#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
182 || ('a' <= (c) && (c) <= 'f') \
183 || ('A' <= (c) && (c) <= 'F'))
184#define isalnum(c) (('0' <= (c) && (c) <= '9') \
185 || ('a' <= (c) && (c) <= 'z') \
186 || ('A' <= (c) && (c) <= 'Z'))
187#define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
188
189static char *help_string = "\
190Commands:\n\
191 b show breakpoints\n\
192 bd set data breakpoint\n\
193 bi set instruction breakpoint\n\
194 bc clear breakpoint\n"
195#ifdef CONFIG_SMP
196 "\
197 c print cpus stopped in xmon\n\
198 c# try to switch to cpu number h (in hex)\n"
199#endif
200 "\
201 C checksum\n\
202 d dump bytes\n\
203 di dump instructions\n\
204 df dump float values\n\
205 dd dump double values\n\
ddadb6b8
ME
206 dl dump the kernel log buffer\n"
207#ifdef CONFIG_PPC64
208 "\
209 dp[#] dump paca for current cpu, or cpu #\n\
210 dpa dump paca for all possible cpus\n"
211#endif
212 "\
7e5b5938 213 dr dump stream of raw bytes\n\
1da177e4
LT
214 e print exception information\n\
215 f flush cache\n\
216 la lookup symbol+offset of specified address\n\
217 ls lookup address of specified symbol\n\
218 m examine/change memory\n\
219 mm move a block of memory\n\
220 ms set a block of memory\n\
221 md compare two blocks of memory\n\
222 ml locate a block of memory\n\
223 mz zero a block of memory\n\
224 mi show information about memory allocation\n\
f78541dc 225 p call a procedure\n\
1da177e4 226 r print registers\n\
ff8a8f25 227 s single step\n"
e055595d 228#ifdef CONFIG_SPU_BASE
ff8a8f25 229" ss stop execution on all spus\n\
a8984970 230 sr restore execution on stopped spus\n\
24a24c85 231 sf # dump spu fields for spu # (in hex)\n\
c99176a2 232 sd # dump spu local store for spu # (in hex)\n\
af89fb80 233 sdi # disassemble spu local store for spu # (in hex)\n"
ff8a8f25
ME
234#endif
235" S print special registers\n\
1da177e4 236 t print backtrace\n\
1da177e4 237 x exit monitor and recover\n\
f78541dc 238 X exit monitor and dont recover\n"
79873e8d 239#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
f78541dc 240" u dump segment table or SLB\n"
79873e8d 241#elif defined(CONFIG_PPC_STD_MMU_32)
f78541dc 242" u dump segment registers\n"
79873e8d 243#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
5a8a1a28
BH
244" u dump TLB\n"
245#endif
f78541dc
PM
246" ? help\n"
247" zr reboot\n\
1da177e4
LT
248 zh halt\n"
249;
250
251static struct pt_regs *xmon_regs;
252
f78541dc 253static inline void sync(void)
1da177e4
LT
254{
255 asm volatile("sync; isync");
256}
257
f78541dc
PM
258static inline void store_inst(void *p)
259{
260 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
261}
262
263static inline void cflush(void *p)
264{
265 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
266}
267
268static inline void cinval(void *p)
269{
270 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
271}
1da177e4
LT
272
273/*
274 * Disable surveillance (the service processor watchdog function)
275 * while we are in xmon.
276 * XXX we should re-enable it when we leave. :)
277 */
278#define SURVEILLANCE_TOKEN 9000
279
280static inline void disable_surveillance(void)
281{
282#ifdef CONFIG_PPC_PSERIES
283 /* Since this can't be a module, args should end up below 4GB. */
284 static struct rtas_args args;
285
286 /*
287 * At this point we have got all the cpus we can into
288 * xmon, so there is hopefully no other cpu calling RTAS
289 * at the moment, even though we don't take rtas.lock.
290 * If we did try to take rtas.lock there would be a
291 * real possibility of deadlock.
292 */
293 args.token = rtas_token("set-indicator");
294 if (args.token == RTAS_UNKNOWN_SERVICE)
295 return;
3b8a3c01
LD
296 args.nargs = cpu_to_be32(3);
297 args.nret = cpu_to_be32(1);
1da177e4 298 args.rets = &args.args[3];
3b8a3c01 299 args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
1da177e4
LT
300 args.args[1] = 0;
301 args.args[2] = 0;
302 enter_rtas(__pa(&args));
303#endif /* CONFIG_PPC_PSERIES */
304}
305
306#ifdef CONFIG_SMP
307static int xmon_speaker;
308
309static void get_output_lock(void)
310{
311 int me = smp_processor_id() + 0x100;
312 int last_speaker = 0, prev;
313 long timeout;
314
315 if (xmon_speaker == me)
316 return;
730efb61 317
1da177e4 318 for (;;) {
730efb61
ME
319 last_speaker = cmpxchg(&xmon_speaker, 0, me);
320 if (last_speaker == 0)
321 return;
322
15075897
ME
323 /*
324 * Wait a full second for the lock, we might be on a slow
325 * console, but check every 100us.
326 */
327 timeout = 10000;
1da177e4 328 while (xmon_speaker == last_speaker) {
15075897
ME
329 if (--timeout > 0) {
330 udelay(100);
1da177e4 331 continue;
15075897
ME
332 }
333
1da177e4
LT
334 /* hostile takeover */
335 prev = cmpxchg(&xmon_speaker, last_speaker, me);
336 if (prev == last_speaker)
337 return;
338 break;
339 }
340 }
341}
342
343static void release_output_lock(void)
344{
345 xmon_speaker = 0;
346}
1c8950ff
ME
347
348int cpus_are_in_xmon(void)
349{
104699c0 350 return !cpumask_empty(&cpus_in_xmon);
1c8950ff 351}
1da177e4
LT
352#endif
353
daf8f403
JB
354static inline int unrecoverable_excp(struct pt_regs *regs)
355{
08f6d6ab 356#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
66857b3a 357 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
daf8f403
JB
358 return 0;
359#else
360 return ((regs->msr & MSR_RI) == 0);
361#endif
362}
363
b0da9856 364static int xmon_core(struct pt_regs *regs, int fromipi)
1da177e4
LT
365{
366 int cmd = 0;
1da177e4
LT
367 struct bpt *bp;
368 long recurse_jmp[JMP_BUF_LEN];
369 unsigned long offset;
f13659e0 370 unsigned long flags;
1da177e4
LT
371#ifdef CONFIG_SMP
372 int cpu;
373 int secondary;
374 unsigned long timeout;
375#endif
376
f13659e0 377 local_irq_save(flags);
a71d64b4 378 hard_irq_disable();
1da177e4
LT
379
380 bp = in_breakpoint_table(regs->nip, &offset);
381 if (bp != NULL) {
382 regs->nip = bp->address + offset;
383 atomic_dec(&bp->ref_count);
384 }
385
386 remove_cpu_bpts();
387
388#ifdef CONFIG_SMP
389 cpu = smp_processor_id();
104699c0 390 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1da177e4
LT
391 get_output_lock();
392 excprint(regs);
393 printf("cpu 0x%x: Exception %lx %s in xmon, "
394 "returning to main loop\n",
395 cpu, regs->trap, getvecname(TRAP(regs)));
5cb4cc0d 396 release_output_lock();
1da177e4
LT
397 longjmp(xmon_fault_jmp[cpu], 1);
398 }
399
400 if (setjmp(recurse_jmp) != 0) {
401 if (!in_xmon || !xmon_gate) {
5cb4cc0d 402 get_output_lock();
1da177e4
LT
403 printf("xmon: WARNING: bad recursive fault "
404 "on cpu 0x%x\n", cpu);
5cb4cc0d 405 release_output_lock();
1da177e4
LT
406 goto waiting;
407 }
408 secondary = !(xmon_taken && cpu == xmon_owner);
409 goto cmdloop;
410 }
411
412 xmon_fault_jmp[cpu] = recurse_jmp;
1da177e4
LT
413
414 bp = NULL;
9f0b0793 415 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
1da177e4 416 bp = at_breakpoint(regs->nip);
daf8f403 417 if (bp || unrecoverable_excp(regs))
1da177e4
LT
418 fromipi = 0;
419
420 if (!fromipi) {
421 get_output_lock();
422 excprint(regs);
423 if (bp) {
736256e4 424 printf("cpu 0x%x stopped at breakpoint 0x%lx (",
1da177e4
LT
425 cpu, BP_NUM(bp));
426 xmon_print_symbol(regs->nip, " ", ")\n");
427 }
daf8f403 428 if (unrecoverable_excp(regs))
1da177e4
LT
429 printf("WARNING: exception is not recoverable, "
430 "can't continue\n");
431 release_output_lock();
432 }
433
d2b496e5
ME
434 cpumask_set_cpu(cpu, &cpus_in_xmon);
435
1da177e4
LT
436 waiting:
437 secondary = 1;
438 while (secondary && !xmon_gate) {
439 if (in_xmon == 0) {
440 if (fromipi)
441 goto leave;
442 secondary = test_and_set_bit(0, &in_xmon);
443 }
444 barrier();
445 }
446
447 if (!secondary && !xmon_gate) {
448 /* we are the first cpu to come in */
449 /* interrupt other cpu(s) */
450 int ncpus = num_online_cpus();
451
452 xmon_owner = cpu;
453 mb();
454 if (ncpus > 1) {
e0476371 455 smp_send_debugger_break();
1da177e4
LT
456 /* wait for other cpus to come in */
457 for (timeout = 100000000; timeout != 0; --timeout) {
104699c0 458 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
1da177e4
LT
459 break;
460 barrier();
461 }
462 }
463 remove_bpts();
464 disable_surveillance();
465 /* for breakpoint or single step, print the current instr. */
466 if (bp || TRAP(regs) == 0xd00)
467 ppc_inst_dump(regs->nip, 1, 0);
468 printf("enter ? for help\n");
469 mb();
470 xmon_gate = 1;
471 barrier();
472 }
473
474 cmdloop:
475 while (in_xmon) {
476 if (secondary) {
477 if (cpu == xmon_owner) {
478 if (!test_and_set_bit(0, &xmon_taken)) {
479 secondary = 0;
480 continue;
481 }
482 /* missed it */
483 while (cpu == xmon_owner)
484 barrier();
485 }
486 barrier();
487 } else {
488 cmd = cmds(regs);
489 if (cmd != 0) {
490 /* exiting xmon */
491 insert_bpts();
492 xmon_gate = 0;
493 wmb();
494 in_xmon = 0;
495 break;
496 }
497 /* have switched to some other cpu */
498 secondary = 1;
499 }
500 }
501 leave:
104699c0 502 cpumask_clear_cpu(cpu, &cpus_in_xmon);
1da177e4 503 xmon_fault_jmp[cpu] = NULL;
1da177e4
LT
504#else
505 /* UP is simple... */
506 if (in_xmon) {
507 printf("Exception %lx %s in xmon, returning to main loop\n",
508 regs->trap, getvecname(TRAP(regs)));
509 longjmp(xmon_fault_jmp[0], 1);
510 }
511 if (setjmp(recurse_jmp) == 0) {
512 xmon_fault_jmp[0] = recurse_jmp;
513 in_xmon = 1;
514
515 excprint(regs);
516 bp = at_breakpoint(regs->nip);
517 if (bp) {
736256e4 518 printf("Stopped at breakpoint %lx (", BP_NUM(bp));
1da177e4
LT
519 xmon_print_symbol(regs->nip, " ", ")\n");
520 }
daf8f403 521 if (unrecoverable_excp(regs))
1da177e4
LT
522 printf("WARNING: exception is not recoverable, "
523 "can't continue\n");
524 remove_bpts();
525 disable_surveillance();
526 /* for breakpoint or single step, print the current instr. */
527 if (bp || TRAP(regs) == 0xd00)
528 ppc_inst_dump(regs->nip, 1, 0);
529 printf("enter ? for help\n");
530 }
531
532 cmd = cmds(regs);
533
534 insert_bpts();
535 in_xmon = 0;
536#endif
537
cdd3904d
JB
538#ifdef CONFIG_BOOKE
539 if (regs->msr & MSR_DE) {
540 bp = at_breakpoint(regs->nip);
541 if (bp != NULL) {
542 regs->nip = (unsigned long) &bp->instr[0];
543 atomic_inc(&bp->ref_count);
544 }
545 }
546#else
9f0b0793 547 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
1da177e4
LT
548 bp = at_breakpoint(regs->nip);
549 if (bp != NULL) {
550 int stepped = emulate_step(regs, bp->instr[0]);
551 if (stepped == 0) {
552 regs->nip = (unsigned long) &bp->instr[0];
553 atomic_inc(&bp->ref_count);
554 } else if (stepped < 0) {
555 printf("Couldn't single-step %s instruction\n",
556 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
557 }
558 }
559 }
cdd3904d 560#endif
1da177e4
LT
561 insert_cpu_bpts();
562
a71d64b4 563 touch_nmi_watchdog();
f13659e0 564 local_irq_restore(flags);
1da177e4 565
0a730ae5 566 return cmd != 'X' && cmd != EOF;
1da177e4
LT
567}
568
569int xmon(struct pt_regs *excp)
570{
571 struct pt_regs regs;
572
573 if (excp == NULL) {
322b4394 574 ppc_save_regs(&regs);
1da177e4
LT
575 excp = &regs;
576 }
ff8a8f25 577
1da177e4
LT
578 return xmon_core(excp, 0);
579}
f78541dc
PM
580EXPORT_SYMBOL(xmon);
581
f583ffce 582irqreturn_t xmon_irq(int irq, void *d)
f78541dc
PM
583{
584 unsigned long flags;
585 local_irq_save(flags);
586 printf("Keyboard interrupt\n");
f583ffce 587 xmon(get_irq_regs());
f78541dc
PM
588 local_irq_restore(flags);
589 return IRQ_HANDLED;
590}
1da177e4 591
b0da9856 592static int xmon_bpt(struct pt_regs *regs)
1da177e4
LT
593{
594 struct bpt *bp;
595 unsigned long offset;
596
9f0b0793 597 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4
LT
598 return 0;
599
600 /* Are we at the trap at bp->instr[1] for some bp? */
601 bp = in_breakpoint_table(regs->nip, &offset);
602 if (bp != NULL && offset == 4) {
603 regs->nip = bp->address + 4;
604 atomic_dec(&bp->ref_count);
605 return 1;
606 }
607
608 /* Are we at a breakpoint? */
609 bp = at_breakpoint(regs->nip);
610 if (!bp)
611 return 0;
612
613 xmon_core(regs, 0);
614
615 return 1;
616}
617
b0da9856 618static int xmon_sstep(struct pt_regs *regs)
1da177e4
LT
619{
620 if (user_mode(regs))
621 return 0;
622 xmon_core(regs, 0);
623 return 1;
624}
625
9422de3e 626static int xmon_break_match(struct pt_regs *regs)
1da177e4 627{
9f0b0793 628 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4 629 return 0;
fd9648df
AB
630 if (dabr.enabled == 0)
631 return 0;
1da177e4
LT
632 xmon_core(regs, 0);
633 return 1;
634}
635
b0da9856 636static int xmon_iabr_match(struct pt_regs *regs)
1da177e4 637{
9f0b0793 638 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4 639 return 0;
9f1067c2 640 if (iabr == NULL)
1da177e4
LT
641 return 0;
642 xmon_core(regs, 0);
643 return 1;
644}
645
b0da9856 646static int xmon_ipi(struct pt_regs *regs)
1da177e4
LT
647{
648#ifdef CONFIG_SMP
104699c0 649 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
1da177e4
LT
650 xmon_core(regs, 1);
651#endif
652 return 0;
653}
654
b0da9856 655static int xmon_fault_handler(struct pt_regs *regs)
1da177e4
LT
656{
657 struct bpt *bp;
658 unsigned long offset;
659
660 if (in_xmon && catch_memory_errors)
661 handle_fault(regs); /* doesn't return */
662
9f0b0793 663 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
1da177e4
LT
664 bp = in_breakpoint_table(regs->nip, &offset);
665 if (bp != NULL) {
666 regs->nip = bp->address + offset;
667 atomic_dec(&bp->ref_count);
668 }
669 }
670
671 return 0;
672}
673
1da177e4
LT
674static struct bpt *at_breakpoint(unsigned long pc)
675{
676 int i;
677 struct bpt *bp;
678
679 bp = bpts;
680 for (i = 0; i < NBPTS; ++i, ++bp)
681 if (bp->enabled && pc == bp->address)
682 return bp;
683 return NULL;
684}
685
686static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
687{
688 unsigned long off;
689
690 off = nip - (unsigned long) bpts;
691 if (off >= sizeof(bpts))
692 return NULL;
693 off %= sizeof(struct bpt);
694 if (off != offsetof(struct bpt, instr[0])
695 && off != offsetof(struct bpt, instr[1]))
696 return NULL;
697 *offp = off - offsetof(struct bpt, instr[0]);
698 return (struct bpt *) (nip - off);
699}
700
701static struct bpt *new_breakpoint(unsigned long a)
702{
703 struct bpt *bp;
704
705 a &= ~3UL;
706 bp = at_breakpoint(a);
707 if (bp)
708 return bp;
709
710 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
711 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
712 bp->address = a;
713 bp->instr[1] = bpinstr;
714 store_inst(&bp->instr[1]);
715 return bp;
716 }
717 }
718
719 printf("Sorry, no free breakpoints. Please clear one first.\n");
720 return NULL;
721}
722
723static void insert_bpts(void)
724{
725 int i;
726 struct bpt *bp;
727
728 bp = bpts;
729 for (i = 0; i < NBPTS; ++i, ++bp) {
730 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
731 continue;
732 if (mread(bp->address, &bp->instr[0], 4) != 4) {
733 printf("Couldn't read instruction at %lx, "
734 "disabling breakpoint there\n", bp->address);
735 bp->enabled = 0;
736 continue;
737 }
738 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
739 printf("Breakpoint at %lx is on an mtmsrd or rfid "
740 "instruction, disabling it\n", bp->address);
741 bp->enabled = 0;
742 continue;
743 }
744 store_inst(&bp->instr[0]);
745 if (bp->enabled & BP_IABR)
746 continue;
747 if (mwrite(bp->address, &bpinstr, 4) != 4) {
748 printf("Couldn't write instruction at %lx, "
749 "disabling breakpoint there\n", bp->address);
750 bp->enabled &= ~BP_TRAP;
751 continue;
752 }
753 store_inst((void *)bp->address);
754 }
755}
756
757static void insert_cpu_bpts(void)
758{
9422de3e
MN
759 struct arch_hw_breakpoint brk;
760
761 if (dabr.enabled) {
762 brk.address = dabr.address;
763 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
764 brk.len = 8;
21f58507 765 __set_breakpoint(&brk);
9422de3e 766 }
1da177e4 767 if (iabr && cpu_has_feature(CPU_FTR_IABR))
f78541dc 768 mtspr(SPRN_IABR, iabr->address
1da177e4
LT
769 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
770}
771
772static void remove_bpts(void)
773{
774 int i;
775 struct bpt *bp;
776 unsigned instr;
777
778 bp = bpts;
779 for (i = 0; i < NBPTS; ++i, ++bp) {
780 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
781 continue;
782 if (mread(bp->address, &instr, 4) == 4
783 && instr == bpinstr
784 && mwrite(bp->address, &bp->instr, 4) != 4)
785 printf("Couldn't remove breakpoint at %lx\n",
786 bp->address);
787 else
788 store_inst((void *)bp->address);
789 }
790}
791
792static void remove_cpu_bpts(void)
793{
9422de3e 794 hw_breakpoint_disable();
1da177e4 795 if (cpu_has_feature(CPU_FTR_IABR))
f78541dc 796 mtspr(SPRN_IABR, 0);
1da177e4
LT
797}
798
799/* Command interpreting routine */
800static char *last_cmd;
801
802static int
803cmds(struct pt_regs *excp)
804{
805 int cmd = 0;
806
807 last_cmd = NULL;
808 xmon_regs = excp;
26c8af5f
OH
809
810 if (!xmon_no_auto_backtrace) {
811 xmon_no_auto_backtrace = 1;
812 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
813 }
814
1da177e4
LT
815 for(;;) {
816#ifdef CONFIG_SMP
817 printf("%x:", smp_processor_id());
818#endif /* CONFIG_SMP */
819 printf("mon> ");
1da177e4
LT
820 flush_input();
821 termch = 0;
822 cmd = skipbl();
823 if( cmd == '\n' ) {
824 if (last_cmd == NULL)
825 continue;
826 take_input(last_cmd);
827 last_cmd = NULL;
828 cmd = inchar();
829 }
830 switch (cmd) {
831 case 'm':
832 cmd = inchar();
833 switch (cmd) {
834 case 'm':
835 case 's':
836 case 'd':
837 memops(cmd);
838 break;
839 case 'l':
840 memlocate();
841 break;
842 case 'z':
843 memzcan();
844 break;
845 case 'i':
b2b755b5 846 show_mem(0);
1da177e4
LT
847 break;
848 default:
849 termch = cmd;
850 memex();
851 }
852 break;
853 case 'd':
854 dump();
855 break;
856 case 'l':
857 symbol_lookup();
858 break;
859 case 'r':
860 prregs(excp); /* print regs */
861 break;
862 case 'e':
863 excprint(excp);
864 break;
865 case 'S':
866 super_regs();
867 break;
868 case 't':
869 backtrace(excp);
870 break;
871 case 'f':
872 cacheflush();
873 break;
874 case 's':
ff8a8f25
ME
875 if (do_spu_cmd() == 0)
876 break;
1da177e4
LT
877 if (do_step(excp))
878 return cmd;
879 break;
880 case 'x':
881 case 'X':
bb6b9b28 882 return cmd;
1da177e4 883 case EOF:
bb6b9b28
BH
884 printf(" <no input ...>\n");
885 mdelay(2000);
1da177e4
LT
886 return cmd;
887 case '?':
4d404edc 888 xmon_puts(help_string);
1da177e4 889 break;
1da177e4
LT
890 case 'b':
891 bpt_cmds();
892 break;
893 case 'C':
894 csum();
895 break;
896 case 'c':
897 if (cpu_cmd())
898 return 0;
899 break;
900 case 'z':
901 bootcmds();
902 break;
f78541dc
PM
903 case 'p':
904 proccall();
1da177e4 905 break;
f78541dc 906#ifdef CONFIG_PPC_STD_MMU
1da177e4
LT
907 case 'u':
908 dump_segments();
909 break;
79873e8d 910#elif defined(CONFIG_4xx)
5a8a1a28
BH
911 case 'u':
912 dump_tlb_44x();
913 break;
79873e8d 914#elif defined(CONFIG_PPC_BOOK3E)
03247157
BH
915 case 'u':
916 dump_tlb_book3e();
917 break;
f78541dc 918#endif
1da177e4
LT
919 default:
920 printf("Unrecognized command: ");
e3bc8049 921 do {
1da177e4
LT
922 if (' ' < cmd && cmd <= '~')
923 putchar(cmd);
924 else
925 printf("\\x%x", cmd);
926 cmd = inchar();
e3bc8049 927 } while (cmd != '\n');
1da177e4
LT
928 printf(" (type ? for help)\n");
929 break;
930 }
931 }
932}
933
cdd3904d
JB
934#ifdef CONFIG_BOOKE
935static int do_step(struct pt_regs *regs)
936{
937 regs->msr |= MSR_DE;
938 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
939 return 1;
940}
941#else
1da177e4
LT
942/*
943 * Step a single instruction.
944 * Some instructions we emulate, others we execute with MSR_SE set.
945 */
946static int do_step(struct pt_regs *regs)
947{
948 unsigned int instr;
949 int stepped;
950
951 /* check we are in 64-bit kernel mode, translation enabled */
9f0b0793 952 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1da177e4
LT
953 if (mread(regs->nip, &instr, 4) == 4) {
954 stepped = emulate_step(regs, instr);
955 if (stepped < 0) {
956 printf("Couldn't single-step %s instruction\n",
957 (IS_RFID(instr)? "rfid": "mtmsrd"));
958 return 0;
959 }
960 if (stepped > 0) {
961 regs->trap = 0xd00 | (regs->trap & 1);
962 printf("stepped to ");
963 xmon_print_symbol(regs->nip, " ", "\n");
964 ppc_inst_dump(regs->nip, 1, 0);
965 return 0;
966 }
967 }
968 }
969 regs->msr |= MSR_SE;
970 return 1;
971}
cdd3904d 972#endif
1da177e4
LT
973
974static void bootcmds(void)
975{
976 int cmd;
977
978 cmd = inchar();
979 if (cmd == 'r')
980 ppc_md.restart(NULL);
981 else if (cmd == 'h')
982 ppc_md.halt();
983 else if (cmd == 'p')
984 ppc_md.power_off();
985}
986
987static int cpu_cmd(void)
988{
989#ifdef CONFIG_SMP
fd3bb912 990 unsigned long cpu, first_cpu, last_cpu;
1da177e4 991 int timeout;
1da177e4
LT
992
993 if (!scanhex(&cpu)) {
994 /* print cpus waiting or in xmon */
995 printf("cpus stopped:");
fd3bb912 996 last_cpu = first_cpu = NR_CPUS;
bc1d7702 997 for_each_possible_cpu(cpu) {
104699c0 998 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
fd3bb912
PM
999 if (cpu == last_cpu + 1) {
1000 last_cpu = cpu;
1001 } else {
1002 if (last_cpu != first_cpu)
736256e4 1003 printf("-0x%lx", last_cpu);
fd3bb912 1004 last_cpu = first_cpu = cpu;
736256e4 1005 printf(" 0x%lx", cpu);
fd3bb912 1006 }
1da177e4
LT
1007 }
1008 }
fd3bb912 1009 if (last_cpu != first_cpu)
736256e4 1010 printf("-0x%lx", last_cpu);
1da177e4
LT
1011 printf("\n");
1012 return 0;
1013 }
1014 /* try to switch to cpu specified */
104699c0 1015 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
1da177e4
LT
1016 printf("cpu 0x%x isn't in xmon\n", cpu);
1017 return 0;
1018 }
1019 xmon_taken = 0;
1020 mb();
1021 xmon_owner = cpu;
1022 timeout = 10000000;
1023 while (!xmon_taken) {
1024 if (--timeout == 0) {
1025 if (test_and_set_bit(0, &xmon_taken))
1026 break;
1027 /* take control back */
1028 mb();
1029 xmon_owner = smp_processor_id();
736256e4 1030 printf("cpu 0x%x didn't take control\n", cpu);
1da177e4
LT
1031 return 0;
1032 }
1033 barrier();
1034 }
1035 return 1;
1036#else
1037 return 0;
1038#endif /* CONFIG_SMP */
1039}
1040
1041static unsigned short fcstab[256] = {
1042 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1043 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1044 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1045 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1046 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1047 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1048 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1049 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1050 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1051 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1052 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1053 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1054 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1055 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1056 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1057 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1058 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1059 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1060 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1061 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1062 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1063 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1064 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1065 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1066 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1067 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1068 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1069 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1070 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1071 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1072 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1073 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1074};
1075
1076#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1077
1078static void
1079csum(void)
1080{
1081 unsigned int i;
1082 unsigned short fcs;
1083 unsigned char v;
1084
1085 if (!scanhex(&adrs))
1086 return;
1087 if (!scanhex(&ncsum))
1088 return;
1089 fcs = 0xffff;
1090 for (i = 0; i < ncsum; ++i) {
1091 if (mread(adrs+i, &v, 1) == 0) {
736256e4 1092 printf("csum stopped at "REG"\n", adrs+i);
1da177e4
LT
1093 break;
1094 }
1095 fcs = FCS(fcs, v);
1096 }
1097 printf("%x\n", fcs);
1098}
1099
1100/*
1101 * Check if this is a suitable place to put a breakpoint.
1102 */
1103static long check_bp_loc(unsigned long addr)
1104{
1105 unsigned int instr;
1106
1107 addr &= ~3;
51fae6de 1108 if (!is_kernel_addr(addr)) {
1da177e4
LT
1109 printf("Breakpoints may only be placed at kernel addresses\n");
1110 return 0;
1111 }
1112 if (!mread(addr, &instr, sizeof(instr))) {
1113 printf("Can't read instruction at address %lx\n", addr);
1114 return 0;
1115 }
1116 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1117 printf("Breakpoints may not be placed on mtmsrd or rfid "
1118 "instructions\n");
1119 return 0;
1120 }
1121 return 1;
1122}
1123
e3bc8049 1124static char *breakpoint_help_string =
1da177e4
LT
1125 "Breakpoint command usage:\n"
1126 "b show breakpoints\n"
1127 "b <addr> [cnt] set breakpoint at given instr addr\n"
1128 "bc clear all breakpoints\n"
1129 "bc <n/addr> clear breakpoint number n or at addr\n"
1130 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1131 "bd <addr> [cnt] set hardware data breakpoint\n"
1132 "";
1133
1134static void
1135bpt_cmds(void)
1136{
1137 int cmd;
1138 unsigned long a;
1139 int mode, i;
1140 struct bpt *bp;
1141 const char badaddr[] = "Only kernel addresses are permitted "
1142 "for breakpoints\n";
1143
1144 cmd = inchar();
1145 switch (cmd) {
f78541dc 1146#ifndef CONFIG_8xx
1da177e4
LT
1147 case 'd': /* bd - hardware data breakpoint */
1148 mode = 7;
1149 cmd = inchar();
1150 if (cmd == 'r')
1151 mode = 5;
1152 else if (cmd == 'w')
1153 mode = 6;
1154 else
1155 termch = cmd;
1156 dabr.address = 0;
1157 dabr.enabled = 0;
1158 if (scanhex(&dabr.address)) {
51fae6de 1159 if (!is_kernel_addr(dabr.address)) {
1da177e4
LT
1160 printf(badaddr);
1161 break;
1162 }
9422de3e 1163 dabr.address &= ~HW_BRK_TYPE_DABR;
1da177e4
LT
1164 dabr.enabled = mode | BP_DABR;
1165 }
1166 break;
1167
1168 case 'i': /* bi - hardware instr breakpoint */
1169 if (!cpu_has_feature(CPU_FTR_IABR)) {
1170 printf("Hardware instruction breakpoint "
1171 "not supported on this cpu\n");
1172 break;
1173 }
1174 if (iabr) {
1175 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1176 iabr = NULL;
1177 }
1178 if (!scanhex(&a))
1179 break;
1180 if (!check_bp_loc(a))
1181 break;
1182 bp = new_breakpoint(a);
1183 if (bp != NULL) {
1184 bp->enabled |= BP_IABR | BP_IABR_TE;
1185 iabr = bp;
1186 }
1187 break;
f78541dc 1188#endif
1da177e4
LT
1189
1190 case 'c':
1191 if (!scanhex(&a)) {
1192 /* clear all breakpoints */
1193 for (i = 0; i < NBPTS; ++i)
1194 bpts[i].enabled = 0;
1195 iabr = NULL;
1196 dabr.enabled = 0;
1197 printf("All breakpoints cleared\n");
1198 break;
1199 }
1200
1201 if (a <= NBPTS && a >= 1) {
1202 /* assume a breakpoint number */
1203 bp = &bpts[a-1]; /* bp nums are 1 based */
1204 } else {
1205 /* assume a breakpoint address */
1206 bp = at_breakpoint(a);
9f1067c2 1207 if (bp == NULL) {
736256e4 1208 printf("No breakpoint at %lx\n", a);
1da177e4
LT
1209 break;
1210 }
1211 }
1212
736256e4 1213 printf("Cleared breakpoint %lx (", BP_NUM(bp));
1da177e4
LT
1214 xmon_print_symbol(bp->address, " ", ")\n");
1215 bp->enabled = 0;
1216 break;
1217
1218 default:
1219 termch = cmd;
e3bc8049 1220 cmd = skipbl();
1da177e4
LT
1221 if (cmd == '?') {
1222 printf(breakpoint_help_string);
1223 break;
1224 }
1225 termch = cmd;
1226 if (!scanhex(&a)) {
1227 /* print all breakpoints */
1228 printf(" type address\n");
1229 if (dabr.enabled) {
f78541dc 1230 printf(" data "REG" [", dabr.address);
1da177e4
LT
1231 if (dabr.enabled & 1)
1232 printf("r");
1233 if (dabr.enabled & 2)
1234 printf("w");
1235 printf("]\n");
1236 }
1237 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1238 if (!bp->enabled)
1239 continue;
1240 printf("%2x %s ", BP_NUM(bp),
1241 (bp->enabled & BP_IABR)? "inst": "trap");
1242 xmon_print_symbol(bp->address, " ", "\n");
1243 }
1244 break;
1245 }
1246
1247 if (!check_bp_loc(a))
1248 break;
1249 bp = new_breakpoint(a);
1250 if (bp != NULL)
1251 bp->enabled |= BP_TRAP;
1252 break;
1253 }
1254}
1255
1256/* Very cheap human name for vector lookup. */
1257static
1258const char *getvecname(unsigned long vec)
1259{
1260 char *ret;
1261
1262 switch (vec) {
1263 case 0x100: ret = "(System Reset)"; break;
1264 case 0x200: ret = "(Machine Check)"; break;
1265 case 0x300: ret = "(Data Access)"; break;
1266 case 0x380: ret = "(Data SLB Access)"; break;
1267 case 0x400: ret = "(Instruction Access)"; break;
1268 case 0x480: ret = "(Instruction SLB Access)"; break;
1269 case 0x500: ret = "(Hardware Interrupt)"; break;
1270 case 0x600: ret = "(Alignment)"; break;
1271 case 0x700: ret = "(Program Check)"; break;
1272 case 0x800: ret = "(FPU Unavailable)"; break;
1273 case 0x900: ret = "(Decrementer)"; break;
660e034c
ME
1274 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1275 case 0xa00: ret = "(Doorbell)"; break;
1da177e4
LT
1276 case 0xc00: ret = "(System Call)"; break;
1277 case 0xd00: ret = "(Single Step)"; break;
660e034c
ME
1278 case 0xe40: ret = "(Emulation Assist)"; break;
1279 case 0xe60: ret = "(HMI)"; break;
1280 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1da177e4
LT
1281 case 0xf00: ret = "(Performance Monitor)"; break;
1282 case 0xf20: ret = "(Altivec Unavailable)"; break;
1283 case 0x1300: ret = "(Instruction Breakpoint)"; break;
660e034c
ME
1284 case 0x1500: ret = "(Denormalisation)"; break;
1285 case 0x1700: ret = "(Altivec Assist)"; break;
1da177e4
LT
1286 default: ret = "";
1287 }
1288 return ret;
1289}
1290
1291static void get_function_bounds(unsigned long pc, unsigned long *startp,
1292 unsigned long *endp)
1293{
1294 unsigned long size, offset;
1295 const char *name;
1da177e4
LT
1296
1297 *startp = *endp = 0;
1298 if (pc == 0)
1299 return;
1300 if (setjmp(bus_error_jmp) == 0) {
1301 catch_memory_errors = 1;
1302 sync();
ffb45122 1303 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1da177e4
LT
1304 if (name != NULL) {
1305 *startp = pc - offset;
1306 *endp = pc - offset + size;
1307 }
1308 sync();
1309 }
1310 catch_memory_errors = 0;
1311}
1312
ec2b36b9
BH
1313#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1314#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1315
1da177e4
LT
1316static void xmon_show_stack(unsigned long sp, unsigned long lr,
1317 unsigned long pc)
1318{
0104cd68 1319 int max_to_print = 64;
1da177e4
LT
1320 unsigned long ip;
1321 unsigned long newsp;
1322 unsigned long marker;
1da177e4
LT
1323 struct pt_regs regs;
1324
0104cd68 1325 while (max_to_print--) {
1da177e4
LT
1326 if (sp < PAGE_OFFSET) {
1327 if (sp != 0)
1328 printf("SP (%lx) is in userspace\n", sp);
1329 break;
1330 }
1331
f78541dc 1332 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1da177e4
LT
1333 || !mread(sp, &newsp, sizeof(unsigned long))) {
1334 printf("Couldn't read stack frame at %lx\n", sp);
1335 break;
1336 }
1337
1338 /*
1339 * For the first stack frame, try to work out if
1340 * LR and/or the saved LR value in the bottommost
1341 * stack frame are valid.
1342 */
1343 if ((pc | lr) != 0) {
1344 unsigned long fnstart, fnend;
1345 unsigned long nextip;
1346 int printip = 1;
1347
1348 get_function_bounds(pc, &fnstart, &fnend);
1349 nextip = 0;
1350 if (newsp > sp)
f78541dc 1351 mread(newsp + LRSAVE_OFFSET, &nextip,
1da177e4
LT
1352 sizeof(unsigned long));
1353 if (lr == ip) {
1354 if (lr < PAGE_OFFSET
1355 || (fnstart <= lr && lr < fnend))
1356 printip = 0;
1357 } else if (lr == nextip) {
1358 printip = 0;
1359 } else if (lr >= PAGE_OFFSET
1360 && !(fnstart <= lr && lr < fnend)) {
1361 printf("[link register ] ");
1362 xmon_print_symbol(lr, " ", "\n");
1363 }
1364 if (printip) {
f78541dc 1365 printf("["REG"] ", sp);
1da177e4
LT
1366 xmon_print_symbol(ip, " ", " (unreliable)\n");
1367 }
1368 pc = lr = 0;
1369
1370 } else {
f78541dc 1371 printf("["REG"] ", sp);
1da177e4
LT
1372 xmon_print_symbol(ip, " ", "\n");
1373 }
1374
1375 /* Look for "regshere" marker to see if this is
1376 an exception frame. */
f78541dc 1377 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
ec2b36b9 1378 && marker == STACK_FRAME_REGS_MARKER) {
c4de3809 1379 if (mread(sp + STACK_FRAME_OVERHEAD, &regs, sizeof(regs))
1da177e4
LT
1380 != sizeof(regs)) {
1381 printf("Couldn't read registers at %lx\n",
c4de3809 1382 sp + STACK_FRAME_OVERHEAD);
1da177e4
LT
1383 break;
1384 }
e3bc8049 1385 printf("--- Exception: %lx %s at ", regs.trap,
1da177e4
LT
1386 getvecname(TRAP(&regs)));
1387 pc = regs.nip;
1388 lr = regs.link;
1389 xmon_print_symbol(pc, " ", "\n");
1390 }
1391
1392 if (newsp == 0)
1393 break;
1394
1395 sp = newsp;
0104cd68 1396 }
1da177e4
LT
1397}
1398
1399static void backtrace(struct pt_regs *excp)
1400{
1401 unsigned long sp;
1402
1403 if (scanhex(&sp))
1404 xmon_show_stack(sp, 0, 0);
1405 else
1406 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1407 scannl();
1408}
1409
1410static void print_bug_trap(struct pt_regs *regs)
1411{
ebdba9af 1412#ifdef CONFIG_BUG
73c9ceab 1413 const struct bug_entry *bug;
1da177e4
LT
1414 unsigned long addr;
1415
1416 if (regs->msr & MSR_PR)
1417 return; /* not in kernel */
1418 addr = regs->nip; /* address of trap instruction */
1419 if (addr < PAGE_OFFSET)
1420 return;
1421 bug = find_bug(regs->nip);
1422 if (bug == NULL)
1423 return;
73c9ceab 1424 if (is_warning_bug(bug))
1da177e4
LT
1425 return;
1426
0a7c7efc 1427#ifdef CONFIG_DEBUG_BUGVERBOSE
73c9ceab
JF
1428 printf("kernel BUG at %s:%u!\n",
1429 bug->file, bug->line);
0a7c7efc
SR
1430#else
1431 printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
1432#endif
ebdba9af 1433#endif /* CONFIG_BUG */
1da177e4
LT
1434}
1435
9f1067c2 1436static void excprint(struct pt_regs *fp)
1da177e4
LT
1437{
1438 unsigned long trap;
1439
1440#ifdef CONFIG_SMP
1441 printf("cpu 0x%x: ", smp_processor_id());
1442#endif /* CONFIG_SMP */
1443
1444 trap = TRAP(fp);
1445 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1446 printf(" pc: ");
1447 xmon_print_symbol(fp->nip, ": ", "\n");
1448
1449 printf(" lr: ", fp->link);
1450 xmon_print_symbol(fp->link, ": ", "\n");
1451
1452 printf(" sp: %lx\n", fp->gpr[1]);
1453 printf(" msr: %lx\n", fp->msr);
1454
ce54152f 1455 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1da177e4
LT
1456 printf(" dar: %lx\n", fp->dar);
1457 if (trap != 0x380)
1458 printf(" dsisr: %lx\n", fp->dsisr);
1459 }
1460
1461 printf(" current = 0x%lx\n", current);
f78541dc 1462#ifdef CONFIG_PPC64
7230c564
BH
1463 printf(" paca = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
1464 local_paca, local_paca->soft_enabled, local_paca->irq_happened);
f78541dc 1465#endif
1da177e4
LT
1466 if (current) {
1467 printf(" pid = %ld, comm = %s\n",
1468 current->pid, current->comm);
1469 }
1470
1471 if (trap == 0x700)
1472 print_bug_trap(fp);
1473}
1474
9f1067c2 1475static void prregs(struct pt_regs *fp)
1da177e4 1476{
f78541dc 1477 int n, trap;
1da177e4
LT
1478 unsigned long base;
1479 struct pt_regs regs;
1480
1481 if (scanhex(&base)) {
1482 if (setjmp(bus_error_jmp) == 0) {
1483 catch_memory_errors = 1;
1484 sync();
1485 regs = *(struct pt_regs *)base;
1486 sync();
1487 __delay(200);
1488 } else {
1489 catch_memory_errors = 0;
f78541dc 1490 printf("*** Error reading registers from "REG"\n",
1da177e4
LT
1491 base);
1492 return;
1493 }
1494 catch_memory_errors = 0;
1495 fp = &regs;
1496 }
1497
f78541dc 1498#ifdef CONFIG_PPC64
1da177e4
LT
1499 if (FULL_REGS(fp)) {
1500 for (n = 0; n < 16; ++n)
f78541dc 1501 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1da177e4
LT
1502 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1503 } else {
1504 for (n = 0; n < 7; ++n)
f78541dc 1505 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1da177e4
LT
1506 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1507 }
f78541dc
PM
1508#else
1509 for (n = 0; n < 32; ++n) {
1510 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1511 (n & 3) == 3? "\n": " ");
1512 if (n == 12 && !FULL_REGS(fp)) {
1513 printf("\n");
1514 break;
1515 }
1516 }
1517#endif
1da177e4
LT
1518 printf("pc = ");
1519 xmon_print_symbol(fp->nip, " ", "\n");
48404f2e
PM
1520 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1521 printf("cfar= ");
1522 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1523 }
1da177e4
LT
1524 printf("lr = ");
1525 xmon_print_symbol(fp->link, " ", "\n");
f78541dc
PM
1526 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1527 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1da177e4 1528 fp->ctr, fp->xer, fp->trap);
f78541dc
PM
1529 trap = TRAP(fp);
1530 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1531 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1da177e4
LT
1532}
1533
9f1067c2 1534static void cacheflush(void)
1da177e4
LT
1535{
1536 int cmd;
1537 unsigned long nflush;
1538
1539 cmd = inchar();
1540 if (cmd != 'i')
1541 termch = cmd;
1542 scanhex((void *)&adrs);
1543 if (termch != '\n')
1544 termch = 0;
1545 nflush = 1;
1546 scanhex(&nflush);
1547 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1548 if (setjmp(bus_error_jmp) == 0) {
1549 catch_memory_errors = 1;
1550 sync();
1551
1552 if (cmd != 'i') {
1553 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1554 cflush((void *) adrs);
1555 } else {
1556 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1557 cinval((void *) adrs);
1558 }
1559 sync();
1560 /* wait a little while to see if we get a machine check */
1561 __delay(200);
1562 }
1563 catch_memory_errors = 0;
1564}
1565
9f1067c2 1566static unsigned long
1da177e4
LT
1567read_spr(int n)
1568{
1569 unsigned int instrs[2];
1570 unsigned long (*code)(void);
1da177e4 1571 unsigned long ret = -1UL;
548ccebc
PM
1572#ifdef CONFIG_PPC64
1573 unsigned long opd[3];
1da177e4 1574
1da177e4
LT
1575 opd[0] = (unsigned long)instrs;
1576 opd[1] = 0;
1577 opd[2] = 0;
548ccebc
PM
1578 code = (unsigned long (*)(void)) opd;
1579#else
1580 code = (unsigned long (*)(void)) instrs;
1581#endif
1582
1583 /* mfspr r3,n; blr */
1584 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1585 instrs[1] = 0x4e800020;
1da177e4
LT
1586 store_inst(instrs);
1587 store_inst(instrs+1);
1da177e4
LT
1588
1589 if (setjmp(bus_error_jmp) == 0) {
1590 catch_memory_errors = 1;
1591 sync();
1592
1593 ret = code();
1594
1595 sync();
1596 /* wait a little while to see if we get a machine check */
1597 __delay(200);
1598 n = size;
1599 }
1600
1601 return ret;
1602}
1603
9f1067c2 1604static void
1da177e4
LT
1605write_spr(int n, unsigned long val)
1606{
1607 unsigned int instrs[2];
1608 unsigned long (*code)(unsigned long);
548ccebc 1609#ifdef CONFIG_PPC64
1da177e4
LT
1610 unsigned long opd[3];
1611
1da177e4
LT
1612 opd[0] = (unsigned long)instrs;
1613 opd[1] = 0;
1614 opd[2] = 0;
548ccebc
PM
1615 code = (unsigned long (*)(unsigned long)) opd;
1616#else
1617 code = (unsigned long (*)(unsigned long)) instrs;
1618#endif
1619
1620 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1621 instrs[1] = 0x4e800020;
1da177e4
LT
1622 store_inst(instrs);
1623 store_inst(instrs+1);
1da177e4
LT
1624
1625 if (setjmp(bus_error_jmp) == 0) {
1626 catch_memory_errors = 1;
1627 sync();
1628
1629 code(val);
1630
1631 sync();
1632 /* wait a little while to see if we get a machine check */
1633 __delay(200);
1634 n = size;
1635 }
1636}
1637
1638static unsigned long regno;
1639extern char exc_prolog;
1640extern char dec_exc;
1641
9f1067c2 1642static void super_regs(void)
1da177e4
LT
1643{
1644 int cmd;
1645 unsigned long val;
1da177e4
LT
1646
1647 cmd = skipbl();
1648 if (cmd == '\n') {
e3bc8049 1649 unsigned long sp, toc;
1da177e4
LT
1650 asm("mr %0,1" : "=r" (sp) :);
1651 asm("mr %0,2" : "=r" (toc) :);
1652
f78541dc
PM
1653 printf("msr = "REG" sprg0= "REG"\n",
1654 mfmsr(), mfspr(SPRN_SPRG0));
1655 printf("pvr = "REG" sprg1= "REG"\n",
e3bc8049 1656 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
f78541dc
PM
1657 printf("dec = "REG" sprg2= "REG"\n",
1658 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1659 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1660 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1da177e4
LT
1661
1662 return;
1663 }
1664
1665 scanhex(&regno);
1666 switch (cmd) {
1667 case 'w':
1668 val = read_spr(regno);
1669 scanhex(&val);
1670 write_spr(regno, val);
1671 /* fall through */
1672 case 'r':
1673 printf("spr %lx = %lx\n", regno, read_spr(regno));
1674 break;
1da177e4
LT
1675 }
1676 scannl();
1677}
1678
1679/*
1680 * Stuff for reading and writing memory safely
1681 */
9f1067c2 1682static int
1da177e4
LT
1683mread(unsigned long adrs, void *buf, int size)
1684{
1685 volatile int n;
1686 char *p, *q;
1687
1688 n = 0;
1689 if (setjmp(bus_error_jmp) == 0) {
1690 catch_memory_errors = 1;
1691 sync();
1692 p = (char *)adrs;
1693 q = (char *)buf;
1694 switch (size) {
1695 case 2:
f78541dc 1696 *(u16 *)q = *(u16 *)p;
1da177e4
LT
1697 break;
1698 case 4:
f78541dc 1699 *(u32 *)q = *(u32 *)p;
1da177e4
LT
1700 break;
1701 case 8:
f78541dc 1702 *(u64 *)q = *(u64 *)p;
1da177e4
LT
1703 break;
1704 default:
1705 for( ; n < size; ++n) {
1706 *q++ = *p++;
1707 sync();
1708 }
1709 }
1710 sync();
1711 /* wait a little while to see if we get a machine check */
1712 __delay(200);
1713 n = size;
1714 }
1715 catch_memory_errors = 0;
1716 return n;
1717}
1718
9f1067c2 1719static int
1da177e4
LT
1720mwrite(unsigned long adrs, void *buf, int size)
1721{
1722 volatile int n;
1723 char *p, *q;
1724
1725 n = 0;
1726 if (setjmp(bus_error_jmp) == 0) {
1727 catch_memory_errors = 1;
1728 sync();
1729 p = (char *) adrs;
1730 q = (char *) buf;
1731 switch (size) {
1732 case 2:
f78541dc 1733 *(u16 *)p = *(u16 *)q;
1da177e4
LT
1734 break;
1735 case 4:
f78541dc 1736 *(u32 *)p = *(u32 *)q;
1da177e4
LT
1737 break;
1738 case 8:
f78541dc 1739 *(u64 *)p = *(u64 *)q;
1da177e4
LT
1740 break;
1741 default:
1742 for ( ; n < size; ++n) {
1743 *p++ = *q++;
1744 sync();
1745 }
1746 }
1747 sync();
1748 /* wait a little while to see if we get a machine check */
1749 __delay(200);
1750 n = size;
1751 } else {
736256e4 1752 printf("*** Error writing address "REG"\n", adrs + n);
1da177e4
LT
1753 }
1754 catch_memory_errors = 0;
1755 return n;
1756}
1757
1758static int fault_type;
f78541dc 1759static int fault_except;
1da177e4
LT
1760static char *fault_chars[] = { "--", "**", "##" };
1761
f78541dc 1762static int handle_fault(struct pt_regs *regs)
1da177e4 1763{
f78541dc 1764 fault_except = TRAP(regs);
1da177e4
LT
1765 switch (TRAP(regs)) {
1766 case 0x200:
1767 fault_type = 0;
1768 break;
1769 case 0x300:
1770 case 0x380:
1771 fault_type = 1;
1772 break;
1773 default:
1774 fault_type = 2;
1775 }
1776
1777 longjmp(bus_error_jmp, 1);
1778
1779 return 0;
1780}
1781
1782#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1783
9f1067c2 1784static void
1da177e4
LT
1785byterev(unsigned char *val, int size)
1786{
1787 int t;
1788
1789 switch (size) {
1790 case 2:
1791 SWAP(val[0], val[1], t);
1792 break;
1793 case 4:
1794 SWAP(val[0], val[3], t);
1795 SWAP(val[1], val[2], t);
1796 break;
1797 case 8: /* is there really any use for this? */
1798 SWAP(val[0], val[7], t);
1799 SWAP(val[1], val[6], t);
1800 SWAP(val[2], val[5], t);
1801 SWAP(val[3], val[4], t);
1802 break;
1803 }
1804}
1805
1806static int brev;
1807static int mnoread;
1808
e3bc8049 1809static char *memex_help_string =
1da177e4
LT
1810 "Memory examine command usage:\n"
1811 "m [addr] [flags] examine/change memory\n"
1812 " addr is optional. will start where left off.\n"
1813 " flags may include chars from this set:\n"
1814 " b modify by bytes (default)\n"
1815 " w modify by words (2 byte)\n"
1816 " l modify by longs (4 byte)\n"
1817 " d modify by doubleword (8 byte)\n"
1818 " r toggle reverse byte order mode\n"
1819 " n do not read memory (for i/o spaces)\n"
1820 " . ok to read (default)\n"
1821 "NOTE: flags are saved as defaults\n"
1822 "";
1823
e3bc8049 1824static char *memex_subcmd_help_string =
1da177e4
LT
1825 "Memory examine subcommands:\n"
1826 " hexval write this val to current location\n"
1827 " 'string' write chars from string to this location\n"
1828 " ' increment address\n"
1829 " ^ decrement address\n"
1830 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1831 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1832 " ` clear no-read flag\n"
1833 " ; stay at this addr\n"
1834 " v change to byte mode\n"
1835 " w change to word (2 byte) mode\n"
1836 " l change to long (4 byte) mode\n"
1837 " u change to doubleword (8 byte) mode\n"
1838 " m addr change current addr\n"
1839 " n toggle no-read flag\n"
1840 " r toggle byte reverse flag\n"
1841 " < count back up count bytes\n"
1842 " > count skip forward count bytes\n"
1843 " x exit this mode\n"
1844 "";
1845
9f1067c2 1846static void
1da177e4
LT
1847memex(void)
1848{
1849 int cmd, inc, i, nslash;
1850 unsigned long n;
1851 unsigned char val[16];
1852
1853 scanhex((void *)&adrs);
1854 cmd = skipbl();
1855 if (cmd == '?') {
1856 printf(memex_help_string);
1857 return;
1858 } else {
1859 termch = cmd;
1860 }
1861 last_cmd = "m\n";
1862 while ((cmd = skipbl()) != '\n') {
1863 switch( cmd ){
1864 case 'b': size = 1; break;
1865 case 'w': size = 2; break;
1866 case 'l': size = 4; break;
1867 case 'd': size = 8; break;
1868 case 'r': brev = !brev; break;
1869 case 'n': mnoread = 1; break;
1870 case '.': mnoread = 0; break;
1871 }
1872 }
1873 if( size <= 0 )
1874 size = 1;
1875 else if( size > 8 )
1876 size = 8;
1877 for(;;){
1878 if (!mnoread)
1879 n = mread(adrs, val, size);
e1449ed9 1880 printf(REG"%c", adrs, brev? 'r': ' ');
1da177e4
LT
1881 if (!mnoread) {
1882 if (brev)
1883 byterev(val, size);
1884 putchar(' ');
1885 for (i = 0; i < n; ++i)
1886 printf("%.2x", val[i]);
1887 for (; i < size; ++i)
1888 printf("%s", fault_chars[fault_type]);
1889 }
1890 putchar(' ');
1891 inc = size;
1892 nslash = 0;
1893 for(;;){
1894 if( scanhex(&n) ){
1895 for (i = 0; i < size; ++i)
1896 val[i] = n >> (i * 8);
1897 if (!brev)
1898 byterev(val, size);
1899 mwrite(adrs, val, size);
1900 inc = size;
1901 }
1902 cmd = skipbl();
1903 if (cmd == '\n')
1904 break;
1905 inc = 0;
1906 switch (cmd) {
1907 case '\'':
1908 for(;;){
1909 n = inchar();
1910 if( n == '\\' )
1911 n = bsesc();
1912 else if( n == '\'' )
1913 break;
1914 for (i = 0; i < size; ++i)
1915 val[i] = n >> (i * 8);
1916 if (!brev)
1917 byterev(val, size);
1918 mwrite(adrs, val, size);
1919 adrs += size;
1920 }
1921 adrs -= size;
1922 inc = size;
1923 break;
1924 case ',':
1925 adrs += size;
1926 break;
1927 case '.':
1928 mnoread = 0;
1929 break;
1930 case ';':
1931 break;
1932 case 'x':
1933 case EOF:
1934 scannl();
1935 return;
1936 case 'b':
1937 case 'v':
1938 size = 1;
1939 break;
1940 case 'w':
1941 size = 2;
1942 break;
1943 case 'l':
1944 size = 4;
1945 break;
1946 case 'u':
1947 size = 8;
1948 break;
1949 case '^':
1950 adrs -= size;
1951 break;
1952 break;
1953 case '/':
1954 if (nslash > 0)
1955 adrs -= 1 << nslash;
1956 else
1957 nslash = 0;
1958 nslash += 4;
1959 adrs += 1 << nslash;
1960 break;
1961 case '\\':
1962 if (nslash < 0)
1963 adrs += 1 << -nslash;
1964 else
1965 nslash = 0;
1966 nslash -= 4;
1967 adrs -= 1 << -nslash;
1968 break;
1969 case 'm':
1970 scanhex((void *)&adrs);
1971 break;
1972 case 'n':
1973 mnoread = 1;
1974 break;
1975 case 'r':
1976 brev = !brev;
1977 break;
1978 case '<':
1979 n = size;
1980 scanhex(&n);
1981 adrs -= n;
1982 break;
1983 case '>':
1984 n = size;
1985 scanhex(&n);
1986 adrs += n;
1987 break;
1988 case '?':
1989 printf(memex_subcmd_help_string);
1990 break;
1991 }
1992 }
1993 adrs += inc;
1994 }
1995}
1996
9f1067c2 1997static int
1da177e4
LT
1998bsesc(void)
1999{
2000 int c;
2001
2002 c = inchar();
2003 switch( c ){
2004 case 'n': c = '\n'; break;
2005 case 'r': c = '\r'; break;
2006 case 'b': c = '\b'; break;
2007 case 't': c = '\t'; break;
2008 }
2009 return c;
2010}
2011
7e5b5938
OH
2012static void xmon_rawdump (unsigned long adrs, long ndump)
2013{
2014 long n, m, r, nr;
2015 unsigned char temp[16];
2016
2017 for (n = ndump; n > 0;) {
2018 r = n < 16? n: 16;
2019 nr = mread(adrs, temp, r);
2020 adrs += nr;
2021 for (m = 0; m < r; ++m) {
2022 if (m < nr)
2023 printf("%.2x", temp[m]);
2024 else
2025 printf("%s", fault_chars[fault_type]);
2026 }
2027 n -= r;
2028 if (nr < r)
2029 break;
2030 }
2031 printf("\n");
2032}
2033
ddadb6b8
ME
2034#ifdef CONFIG_PPC64
2035static void dump_one_paca(int cpu)
2036{
2037 struct paca_struct *p;
2038
2039 if (setjmp(bus_error_jmp) != 0) {
2040 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2041 return;
2042 }
2043
2044 catch_memory_errors = 1;
2045 sync();
2046
2047 p = &paca[cpu];
2048
2049 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2050
2051 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
2052 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
2053 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
2054
2055#define DUMP(paca, name, format) \
2056 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2057 offsetof(struct paca_struct, name));
2058
2059 DUMP(p, lock_token, "x");
2060 DUMP(p, paca_index, "x");
2061 DUMP(p, kernel_toc, "lx");
2062 DUMP(p, kernelbase, "lx");
2063 DUMP(p, kernel_msr, "lx");
ddadb6b8 2064 DUMP(p, emergency_sp, "p");
729b0f71
MS
2065#ifdef CONFIG_PPC_BOOK3S_64
2066 DUMP(p, mc_emergency_sp, "p");
2067 DUMP(p, in_mce, "x");
2068#endif
ddadb6b8
ME
2069 DUMP(p, data_offset, "lx");
2070 DUMP(p, hw_cpu_id, "x");
2071 DUMP(p, cpu_start, "x");
2072 DUMP(p, kexec_state, "x");
2073 DUMP(p, __current, "p");
2074 DUMP(p, kstack, "lx");
2075 DUMP(p, stab_rr, "lx");
2076 DUMP(p, saved_r1, "lx");
2077 DUMP(p, trap_save, "x");
2078 DUMP(p, soft_enabled, "x");
2079 DUMP(p, irq_happened, "x");
2080 DUMP(p, io_sync, "x");
2081 DUMP(p, irq_work_pending, "x");
2082 DUMP(p, nap_state_lost, "x");
2083
2084#undef DUMP
2085
2086 catch_memory_errors = 0;
2087 sync();
2088}
2089
2090static void dump_all_pacas(void)
2091{
2092 int cpu;
2093
2094 if (num_possible_cpus() == 0) {
2095 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2096 return;
2097 }
2098
2099 for_each_possible_cpu(cpu)
2100 dump_one_paca(cpu);
2101}
2102
2103static void dump_pacas(void)
2104{
2105 unsigned long num;
2106 int c;
2107
2108 c = inchar();
2109 if (c == 'a') {
2110 dump_all_pacas();
2111 return;
2112 }
2113
2114 termch = c; /* Put c back, it wasn't 'a' */
2115
2116 if (scanhex(&num))
2117 dump_one_paca(num);
2118 else
2119 dump_one_paca(xmon_owner);
2120}
2121#endif
2122
1da177e4
LT
2123#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2124 || ('a' <= (c) && (c) <= 'f') \
2125 || ('A' <= (c) && (c) <= 'F'))
9f1067c2 2126static void
1da177e4
LT
2127dump(void)
2128{
2129 int c;
2130
2131 c = inchar();
ddadb6b8
ME
2132
2133#ifdef CONFIG_PPC64
2134 if (c == 'p') {
2135 dump_pacas();
2136 return;
2137 }
2138#endif
2139
1da177e4
LT
2140 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2141 termch = c;
2142 scanhex((void *)&adrs);
2143 if (termch != '\n')
2144 termch = 0;
2145 if (c == 'i') {
2146 scanhex(&nidump);
2147 if (nidump == 0)
2148 nidump = 16;
2149 else if (nidump > MAX_DUMP)
2150 nidump = MAX_DUMP;
2151 adrs += ppc_inst_dump(adrs, nidump, 1);
2152 last_cmd = "di\n";
f312deb4
VS
2153 } else if (c == 'l') {
2154 dump_log_buf();
7e5b5938
OH
2155 } else if (c == 'r') {
2156 scanhex(&ndump);
2157 if (ndump == 0)
2158 ndump = 64;
2159 xmon_rawdump(adrs, ndump);
2160 adrs += ndump;
2161 last_cmd = "dr\n";
1da177e4
LT
2162 } else {
2163 scanhex(&ndump);
2164 if (ndump == 0)
2165 ndump = 64;
2166 else if (ndump > MAX_DUMP)
2167 ndump = MAX_DUMP;
2168 prdump(adrs, ndump);
2169 adrs += ndump;
2170 last_cmd = "d\n";
2171 }
2172}
2173
9f1067c2 2174static void
1da177e4
LT
2175prdump(unsigned long adrs, long ndump)
2176{
2177 long n, m, c, r, nr;
2178 unsigned char temp[16];
2179
2180 for (n = ndump; n > 0;) {
f78541dc 2181 printf(REG, adrs);
1da177e4
LT
2182 putchar(' ');
2183 r = n < 16? n: 16;
2184 nr = mread(adrs, temp, r);
2185 adrs += nr;
2186 for (m = 0; m < r; ++m) {
e3bc8049 2187 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
e1449ed9 2188 putchar(' ');
1da177e4
LT
2189 if (m < nr)
2190 printf("%.2x", temp[m]);
2191 else
2192 printf("%s", fault_chars[fault_type]);
2193 }
e1449ed9 2194 for (; m < 16; ++m) {
e3bc8049 2195 if ((m & (sizeof(long) - 1)) == 0)
e1449ed9 2196 putchar(' ');
1da177e4 2197 printf(" ");
e1449ed9 2198 }
1da177e4
LT
2199 printf(" |");
2200 for (m = 0; m < r; ++m) {
2201 if (m < nr) {
2202 c = temp[m];
2203 putchar(' ' <= c && c <= '~'? c: '.');
2204 } else
2205 putchar(' ');
2206 }
2207 n -= r;
2208 for (; m < 16; ++m)
2209 putchar(' ');
2210 printf("|\n");
2211 if (nr < r)
2212 break;
2213 }
2214}
2215
4c4c8723
ME
2216typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2217
9f1067c2 2218static int
4c4c8723
ME
2219generic_inst_dump(unsigned long adr, long count, int praddr,
2220 instruction_dump_func dump_func)
1da177e4
LT
2221{
2222 int nr, dotted;
2223 unsigned long first_adr;
2224 unsigned long inst, last_inst = 0;
2225 unsigned char val[4];
2226
2227 dotted = 0;
2228 for (first_adr = adr; count > 0; --count, adr += 4) {
2229 nr = mread(adr, val, 4);
2230 if (nr == 0) {
2231 if (praddr) {
2232 const char *x = fault_chars[fault_type];
f78541dc 2233 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
1da177e4
LT
2234 }
2235 break;
2236 }
2237 inst = GETWORD(val);
2238 if (adr > first_adr && inst == last_inst) {
2239 if (!dotted) {
2240 printf(" ...\n");
2241 dotted = 1;
2242 }
2243 continue;
2244 }
2245 dotted = 0;
2246 last_inst = inst;
2247 if (praddr)
f78541dc 2248 printf(REG" %.8x", adr, inst);
1da177e4 2249 printf("\t");
4c4c8723 2250 dump_func(inst, adr);
1da177e4
LT
2251 printf("\n");
2252 }
2253 return adr - first_adr;
2254}
2255
9f1067c2 2256static int
4c4c8723
ME
2257ppc_inst_dump(unsigned long adr, long count, int praddr)
2258{
2259 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2260}
2261
1da177e4
LT
2262void
2263print_address(unsigned long addr)
2264{
2265 xmon_print_symbol(addr, "\t# ", "");
2266}
2267
f312deb4
VS
2268void
2269dump_log_buf(void)
2270{
ca5dd395
ME
2271 struct kmsg_dumper dumper = { .active = 1 };
2272 unsigned char buf[128];
2273 size_t len;
f312deb4 2274
e3bc8049 2275 if (setjmp(bus_error_jmp) != 0) {
ca5dd395 2276 printf("Error dumping printk buffer!\n");
e3bc8049
ME
2277 return;
2278 }
f312deb4 2279
e3bc8049
ME
2280 catch_memory_errors = 1;
2281 sync();
f312deb4 2282
ca5dd395
ME
2283 kmsg_dump_rewind_nolock(&dumper);
2284 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2285 buf[len] = '\0';
2286 printf("%s", buf);
2287 }
f312deb4 2288
e3bc8049
ME
2289 sync();
2290 /* wait a little while to see if we get a machine check */
2291 __delay(200);
2292 catch_memory_errors = 0;
f312deb4 2293}
1da177e4
LT
2294
2295/*
2296 * Memory operations - move, set, print differences
2297 */
2298static unsigned long mdest; /* destination address */
2299static unsigned long msrc; /* source address */
2300static unsigned long mval; /* byte value to set memory to */
2301static unsigned long mcount; /* # bytes to affect */
2302static unsigned long mdiffs; /* max # differences to print */
2303
9f1067c2 2304static void
1da177e4
LT
2305memops(int cmd)
2306{
2307 scanhex((void *)&mdest);
2308 if( termch != '\n' )
2309 termch = 0;
2310 scanhex((void *)(cmd == 's'? &mval: &msrc));
2311 if( termch != '\n' )
2312 termch = 0;
2313 scanhex((void *)&mcount);
2314 switch( cmd ){
2315 case 'm':
2316 memmove((void *)mdest, (void *)msrc, mcount);
2317 break;
2318 case 's':
2319 memset((void *)mdest, mval, mcount);
2320 break;
2321 case 'd':
2322 if( termch != '\n' )
2323 termch = 0;
2324 scanhex((void *)&mdiffs);
2325 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2326 break;
2327 }
2328}
2329
9f1067c2 2330static void
1da177e4
LT
2331memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2332{
2333 unsigned n, prt;
2334
2335 prt = 0;
2336 for( n = nb; n > 0; --n )
2337 if( *p1++ != *p2++ )
2338 if( ++prt <= maxpr )
2339 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2340 p1[-1], p2 - 1, p2[-1]);
2341 if( prt > maxpr )
2342 printf("Total of %d differences\n", prt);
2343}
2344
2345static unsigned mend;
2346static unsigned mask;
2347
9f1067c2 2348static void
1da177e4
LT
2349memlocate(void)
2350{
2351 unsigned a, n;
2352 unsigned char val[4];
2353
2354 last_cmd = "ml";
2355 scanhex((void *)&mdest);
2356 if (termch != '\n') {
2357 termch = 0;
2358 scanhex((void *)&mend);
2359 if (termch != '\n') {
2360 termch = 0;
2361 scanhex((void *)&mval);
2362 mask = ~0;
2363 if (termch != '\n') termch = 0;
2364 scanhex((void *)&mask);
2365 }
2366 }
2367 n = 0;
2368 for (a = mdest; a < mend; a += 4) {
2369 if (mread(a, val, 4) == 4
2370 && ((GETWORD(val) ^ mval) & mask) == 0) {
2371 printf("%.16x: %.16x\n", a, GETWORD(val));
2372 if (++n >= 10)
2373 break;
2374 }
2375 }
2376}
2377
2378static unsigned long mskip = 0x1000;
2379static unsigned long mlim = 0xffffffff;
2380
9f1067c2 2381static void
1da177e4
LT
2382memzcan(void)
2383{
2384 unsigned char v;
2385 unsigned a;
2386 int ok, ook;
2387
2388 scanhex(&mdest);
2389 if (termch != '\n') termch = 0;
2390 scanhex(&mskip);
2391 if (termch != '\n') termch = 0;
2392 scanhex(&mlim);
2393 ook = 0;
2394 for (a = mdest; a < mlim; a += mskip) {
2395 ok = mread(a, &v, 1);
2396 if (ok && !ook) {
2397 printf("%.8x .. ", a);
1da177e4
LT
2398 } else if (!ok && ook)
2399 printf("%.8x\n", a - mskip);
2400 ook = ok;
2401 if (a + mskip < a)
2402 break;
2403 }
2404 if (ook)
2405 printf("%.8x\n", a - mskip);
2406}
2407
9f1067c2 2408static void proccall(void)
f78541dc
PM
2409{
2410 unsigned long args[8];
2411 unsigned long ret;
2412 int i;
2413 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2414 unsigned long, unsigned long, unsigned long,
2415 unsigned long, unsigned long, unsigned long);
2416 callfunc_t func;
2417
2418 if (!scanhex(&adrs))
2419 return;
2420 if (termch != '\n')
2421 termch = 0;
2422 for (i = 0; i < 8; ++i)
2423 args[i] = 0;
2424 for (i = 0; i < 8; ++i) {
2425 if (!scanhex(&args[i]) || termch == '\n')
2426 break;
2427 termch = 0;
2428 }
2429 func = (callfunc_t) adrs;
2430 ret = 0;
2431 if (setjmp(bus_error_jmp) == 0) {
2432 catch_memory_errors = 1;
2433 sync();
2434 ret = func(args[0], args[1], args[2], args[3],
2435 args[4], args[5], args[6], args[7]);
2436 sync();
736256e4 2437 printf("return value is 0x%lx\n", ret);
f78541dc
PM
2438 } else {
2439 printf("*** %x exception occurred\n", fault_except);
2440 }
2441 catch_memory_errors = 0;
2442}
2443
1da177e4
LT
2444/* Input scanning routines */
2445int
2446skipbl(void)
2447{
2448 int c;
2449
2450 if( termch != 0 ){
2451 c = termch;
2452 termch = 0;
2453 } else
2454 c = inchar();
2455 while( c == ' ' || c == '\t' )
2456 c = inchar();
2457 return c;
2458}
2459
2460#define N_PTREGS 44
2461static char *regnames[N_PTREGS] = {
2462 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2463 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2464 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2465 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
f78541dc
PM
2466 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2467#ifdef CONFIG_PPC64
2468 "softe",
2469#else
2470 "mq",
2471#endif
1da177e4
LT
2472 "trap", "dar", "dsisr", "res"
2473};
2474
2475int
2476scanhex(unsigned long *vp)
2477{
2478 int c, d;
2479 unsigned long v;
2480
2481 c = skipbl();
2482 if (c == '%') {
2483 /* parse register name */
2484 char regname[8];
2485 int i;
2486
2487 for (i = 0; i < sizeof(regname) - 1; ++i) {
2488 c = inchar();
2489 if (!isalnum(c)) {
2490 termch = c;
2491 break;
2492 }
2493 regname[i] = c;
2494 }
2495 regname[i] = 0;
2496 for (i = 0; i < N_PTREGS; ++i) {
2497 if (strcmp(regnames[i], regname) == 0) {
2498 if (xmon_regs == NULL) {
2499 printf("regs not available\n");
2500 return 0;
2501 }
2502 *vp = ((unsigned long *)xmon_regs)[i];
2503 return 1;
2504 }
2505 }
2506 printf("invalid register name '%%%s'\n", regname);
2507 return 0;
2508 }
2509
2510 /* skip leading "0x" if any */
2511
2512 if (c == '0') {
2513 c = inchar();
2514 if (c == 'x') {
2515 c = inchar();
2516 } else {
2517 d = hexdigit(c);
2518 if (d == EOF) {
2519 termch = c;
2520 *vp = 0;
2521 return 1;
2522 }
2523 }
2524 } else if (c == '$') {
2525 int i;
2526 for (i=0; i<63; i++) {
2527 c = inchar();
2528 if (isspace(c)) {
2529 termch = c;
2530 break;
2531 }
2532 tmpstr[i] = c;
2533 }
2534 tmpstr[i++] = 0;
6879dc13
BH
2535 *vp = 0;
2536 if (setjmp(bus_error_jmp) == 0) {
2537 catch_memory_errors = 1;
2538 sync();
2539 *vp = kallsyms_lookup_name(tmpstr);
2540 sync();
2541 }
2542 catch_memory_errors = 0;
1da177e4
LT
2543 if (!(*vp)) {
2544 printf("unknown symbol '%s'\n", tmpstr);
2545 return 0;
2546 }
2547 return 1;
2548 }
2549
2550 d = hexdigit(c);
2551 if (d == EOF) {
2552 termch = c;
2553 return 0;
2554 }
2555 v = 0;
2556 do {
2557 v = (v << 4) + d;
2558 c = inchar();
2559 d = hexdigit(c);
2560 } while (d != EOF);
2561 termch = c;
2562 *vp = v;
2563 return 1;
2564}
2565
9f1067c2 2566static void
1da177e4
LT
2567scannl(void)
2568{
2569 int c;
2570
2571 c = termch;
2572 termch = 0;
2573 while( c != '\n' )
2574 c = inchar();
2575}
2576
9f1067c2 2577static int hexdigit(int c)
1da177e4
LT
2578{
2579 if( '0' <= c && c <= '9' )
2580 return c - '0';
2581 if( 'A' <= c && c <= 'F' )
2582 return c - ('A' - 10);
2583 if( 'a' <= c && c <= 'f' )
2584 return c - ('a' - 10);
2585 return EOF;
2586}
2587
2588void
2589getstring(char *s, int size)
2590{
2591 int c;
2592
2593 c = skipbl();
2594 do {
2595 if( size > 1 ){
2596 *s++ = c;
2597 --size;
2598 }
2599 c = inchar();
2600 } while( c != ' ' && c != '\t' && c != '\n' );
2601 termch = c;
2602 *s = 0;
2603}
2604
2605static char line[256];
2606static char *lineptr;
2607
9f1067c2 2608static void
1da177e4
LT
2609flush_input(void)
2610{
2611 lineptr = NULL;
2612}
2613
9f1067c2 2614static int
1da177e4
LT
2615inchar(void)
2616{
2617 if (lineptr == NULL || *lineptr == 0) {
fca5dcd4 2618 if (xmon_gets(line, sizeof(line)) == NULL) {
1da177e4
LT
2619 lineptr = NULL;
2620 return EOF;
2621 }
2622 lineptr = line;
2623 }
2624 return *lineptr++;
2625}
2626
9f1067c2 2627static void
1da177e4
LT
2628take_input(char *str)
2629{
2630 lineptr = str;
2631}
2632
2633
2634static void
2635symbol_lookup(void)
2636{
2637 int type = inchar();
2638 unsigned long addr;
2639 static char tmp[64];
2640
2641 switch (type) {
2642 case 'a':
2643 if (scanhex(&addr))
2644 xmon_print_symbol(addr, ": ", "\n");
2645 termch = 0;
2646 break;
2647 case 's':
2648 getstring(tmp, 64);
2649 if (setjmp(bus_error_jmp) == 0) {
2650 catch_memory_errors = 1;
2651 sync();
2652 addr = kallsyms_lookup_name(tmp);
2653 if (addr)
2654 printf("%s: %lx\n", tmp, addr);
2655 else
2656 printf("Symbol '%s' not found.\n", tmp);
2657 sync();
2658 }
2659 catch_memory_errors = 0;
2660 termch = 0;
2661 break;
2662 }
2663}
2664
2665
2666/* Print an address in numeric and symbolic form (if possible) */
2667static void xmon_print_symbol(unsigned long address, const char *mid,
2668 const char *after)
2669{
2670 char *modname;
2671 const char *name = NULL;
2672 unsigned long offset, size;
2673
f78541dc 2674 printf(REG, address);
1da177e4
LT
2675 if (setjmp(bus_error_jmp) == 0) {
2676 catch_memory_errors = 1;
2677 sync();
2678 name = kallsyms_lookup(address, &size, &offset, &modname,
2679 tmpstr);
2680 sync();
2681 /* wait a little while to see if we get a machine check */
2682 __delay(200);
2683 }
2684
2685 catch_memory_errors = 0;
2686
2687 if (name) {
2688 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2689 if (modname)
2690 printf(" [%s]", modname);
2691 }
2692 printf("%s", after);
2693}
2694
2d27cfd3 2695#ifdef CONFIG_PPC_BOOK3S_64
13b3d13b 2696void dump_segments(void)
1da177e4
LT
2697{
2698 int i;
b3b9595f 2699 unsigned long esid,vsid,valid;
2700 unsigned long llp;
1da177e4 2701
736256e4 2702 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
1da177e4 2703
584f8b71 2704 for (i = 0; i < mmu_slb_size; i++) {
b3b9595f 2705 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2706 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2707 valid = (esid & SLB_ESID_V);
2708 if (valid | esid | vsid) {
2709 printf("%02d %016lx %016lx", i, esid, vsid);
2710 if (valid) {
2711 llp = vsid & SLB_VSID_LLP;
2712 if (vsid & SLB_VSID_B_1T) {
2713 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2714 GET_ESID_1T(esid),
2715 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2716 llp);
2717 } else {
2718 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2719 GET_ESID(esid),
2720 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2721 llp);
2722 }
2723 } else
2724 printf("\n");
2725 }
1da177e4
LT
2726 }
2727}
f78541dc
PM
2728#endif
2729
2730#ifdef CONFIG_PPC_STD_MMU_32
2731void dump_segments(void)
2732{
2733 int i;
2734
2735 printf("sr0-15 =");
2736 for (i = 0; i < 16; ++i)
2737 printf(" %x", mfsrin(i));
2738 printf("\n");
2739}
2740#endif
2741
5a8a1a28
BH
2742#ifdef CONFIG_44x
2743static void dump_tlb_44x(void)
2744{
2745 int i;
2746
2747 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2748 unsigned long w0,w1,w2;
2749 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2750 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2751 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2752 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2753 if (w0 & PPC44x_TLB_VALID) {
2754 printf("V %08x -> %01x%08x %c%c%c%c%c",
2755 w0 & PPC44x_TLB_EPN_MASK,
2756 w1 & PPC44x_TLB_ERPN_MASK,
2757 w1 & PPC44x_TLB_RPN_MASK,
2758 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2759 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2760 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2761 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2762 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2763 }
2764 printf("\n");
2765 }
2766}
2767#endif /* CONFIG_44x */
9f1067c2 2768
03247157
BH
2769#ifdef CONFIG_PPC_BOOK3E
2770static void dump_tlb_book3e(void)
2771{
2772 u32 mmucfg, pidmask, lpidmask;
2773 u64 ramask;
2774 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
2775 int mmu_version;
2776 static const char *pgsz_names[] = {
2777 " 1K",
2778 " 2K",
2779 " 4K",
2780 " 8K",
2781 " 16K",
2782 " 32K",
2783 " 64K",
2784 "128K",
2785 "256K",
2786 "512K",
2787 " 1M",
2788 " 2M",
2789 " 4M",
2790 " 8M",
2791 " 16M",
2792 " 32M",
2793 " 64M",
2794 "128M",
2795 "256M",
2796 "512M",
2797 " 1G",
2798 " 2G",
2799 " 4G",
2800 " 8G",
2801 " 16G",
2802 " 32G",
2803 " 64G",
2804 "128G",
2805 "256G",
2806 "512G",
2807 " 1T",
2808 " 2T",
2809 };
2810
2811 /* Gather some infos about the MMU */
2812 mmucfg = mfspr(SPRN_MMUCFG);
2813 mmu_version = (mmucfg & 3) + 1;
2814 ntlbs = ((mmucfg >> 2) & 3) + 1;
2815 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
2816 lpidsz = (mmucfg >> 24) & 0xf;
2817 rasz = (mmucfg >> 16) & 0x7f;
2818 if ((mmu_version > 1) && (mmucfg & 0x10000))
2819 lrat = 1;
2820 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
2821 mmu_version, ntlbs, pidsz, lpidsz, rasz);
2822 pidmask = (1ul << pidsz) - 1;
2823 lpidmask = (1ul << lpidsz) - 1;
2824 ramask = (1ull << rasz) - 1;
2825
2826 for (tlb = 0; tlb < ntlbs; tlb++) {
2827 u32 tlbcfg;
2828 int nent, assoc, new_cc = 1;
2829 printf("TLB %d:\n------\n", tlb);
2830 switch(tlb) {
2831 case 0:
2832 tlbcfg = mfspr(SPRN_TLB0CFG);
2833 break;
2834 case 1:
2835 tlbcfg = mfspr(SPRN_TLB1CFG);
2836 break;
2837 case 2:
2838 tlbcfg = mfspr(SPRN_TLB2CFG);
2839 break;
2840 case 3:
2841 tlbcfg = mfspr(SPRN_TLB3CFG);
2842 break;
2843 default:
2844 printf("Unsupported TLB number !\n");
2845 continue;
2846 }
2847 nent = tlbcfg & 0xfff;
2848 assoc = (tlbcfg >> 24) & 0xff;
2849 for (i = 0; i < nent; i++) {
2850 u32 mas0 = MAS0_TLBSEL(tlb);
2851 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
2852 u64 mas2 = 0;
2853 u64 mas7_mas3;
2854 int esel = i, cc = i;
2855
2856 if (assoc != 0) {
2857 cc = i / assoc;
2858 esel = i % assoc;
2859 mas2 = cc * 0x1000;
2860 }
2861
2862 mas0 |= MAS0_ESEL(esel);
2863 mtspr(SPRN_MAS0, mas0);
2864 mtspr(SPRN_MAS1, mas1);
2865 mtspr(SPRN_MAS2, mas2);
2866 asm volatile("tlbre 0,0,0" : : : "memory");
2867 mas1 = mfspr(SPRN_MAS1);
2868 mas2 = mfspr(SPRN_MAS2);
2869 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
2870 if (assoc && (i % assoc) == 0)
2871 new_cc = 1;
2872 if (!(mas1 & MAS1_VALID))
2873 continue;
2874 if (assoc == 0)
2875 printf("%04x- ", i);
2876 else if (new_cc)
2877 printf("%04x-%c", cc, 'A' + esel);
2878 else
2879 printf(" |%c", 'A' + esel);
2880 new_cc = 0;
2881 printf(" %016llx %04x %s %c%c AS%c",
2882 mas2 & ~0x3ffull,
2883 (mas1 >> 16) & 0x3fff,
2884 pgsz_names[(mas1 >> 7) & 0x1f],
2885 mas1 & MAS1_IND ? 'I' : ' ',
2886 mas1 & MAS1_IPROT ? 'P' : ' ',
2887 mas1 & MAS1_TS ? '1' : '0');
2888 printf(" %c%c%c%c%c%c%c",
2889 mas2 & MAS2_X0 ? 'a' : ' ',
2890 mas2 & MAS2_X1 ? 'v' : ' ',
2891 mas2 & MAS2_W ? 'w' : ' ',
2892 mas2 & MAS2_I ? 'i' : ' ',
2893 mas2 & MAS2_M ? 'm' : ' ',
2894 mas2 & MAS2_G ? 'g' : ' ',
2895 mas2 & MAS2_E ? 'e' : ' ');
2896 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
2897 if (mas1 & MAS1_IND)
2898 printf(" %s\n",
2899 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
2900 else
2901 printf(" U%c%c%c S%c%c%c\n",
2902 mas7_mas3 & MAS3_UX ? 'x' : ' ',
2903 mas7_mas3 & MAS3_UW ? 'w' : ' ',
2904 mas7_mas3 & MAS3_UR ? 'r' : ' ',
2905 mas7_mas3 & MAS3_SX ? 'x' : ' ',
2906 mas7_mas3 & MAS3_SW ? 'w' : ' ',
2907 mas7_mas3 & MAS3_SR ? 'r' : ' ');
2908 }
2909 }
2910}
2911#endif /* CONFIG_PPC_BOOK3E */
2912
9f1067c2 2913static void xmon_init(int enable)
b13cfd17
OH
2914{
2915 if (enable) {
2916 __debugger = xmon;
2917 __debugger_ipi = xmon_ipi;
2918 __debugger_bpt = xmon_bpt;
2919 __debugger_sstep = xmon_sstep;
2920 __debugger_iabr_match = xmon_iabr_match;
9422de3e 2921 __debugger_break_match = xmon_break_match;
b13cfd17
OH
2922 __debugger_fault_handler = xmon_fault_handler;
2923 } else {
2924 __debugger = NULL;
2925 __debugger_ipi = NULL;
2926 __debugger_bpt = NULL;
2927 __debugger_sstep = NULL;
2928 __debugger_iabr_match = NULL;
9422de3e 2929 __debugger_break_match = NULL;
b13cfd17
OH
2930 __debugger_fault_handler = NULL;
2931 }
1da177e4 2932}
fca5dcd4
PM
2933
2934#ifdef CONFIG_MAGIC_SYSRQ
1495cc9d 2935static void sysrq_handle_xmon(int key)
fca5dcd4
PM
2936{
2937 /* ensure xmon is enabled */
2938 xmon_init(1);
7d12e780 2939 debugger(get_irq_regs());
fca5dcd4
PM
2940}
2941
1495cc9d 2942static struct sysrq_key_op sysrq_xmon_op = {
fca5dcd4 2943 .handler = sysrq_handle_xmon,
90a102e5 2944 .help_msg = "xmon(x)",
fca5dcd4
PM
2945 .action_msg = "Entering xmon",
2946};
2947
2948static int __init setup_xmon_sysrq(void)
2949{
2950 register_sysrq_key('x', &sysrq_xmon_op);
2951 return 0;
2952}
2953__initcall(setup_xmon_sysrq);
2954#endif /* CONFIG_MAGIC_SYSRQ */
47679283 2955
f5e6a280 2956static int __initdata xmon_early, xmon_off;
47679283
ME
2957
2958static int __init early_parse_xmon(char *p)
2959{
2960 if (!p || strncmp(p, "early", 5) == 0) {
2961 /* just "xmon" is equivalent to "xmon=early" */
2962 xmon_init(1);
2963 xmon_early = 1;
2964 } else if (strncmp(p, "on", 2) == 0)
2965 xmon_init(1);
2966 else if (strncmp(p, "off", 3) == 0)
2967 xmon_off = 1;
2968 else if (strncmp(p, "nobt", 4) == 0)
2969 xmon_no_auto_backtrace = 1;
2970 else
2971 return 1;
2972
2973 return 0;
2974}
2975early_param("xmon", early_parse_xmon);
2976
2977void __init xmon_setup(void)
2978{
2979#ifdef CONFIG_XMON_DEFAULT
2980 if (!xmon_off)
2981 xmon_init(1);
2982#endif
2983 if (xmon_early)
2984 debugger(NULL);
2985}
ff8a8f25 2986
e055595d 2987#ifdef CONFIG_SPU_BASE
ff8a8f25
ME
2988
2989struct spu_info {
2990 struct spu *spu;
2991 u64 saved_mfc_sr1_RW;
2992 u32 saved_spu_runcntl_RW;
24a24c85 2993 unsigned long dump_addr;
ff8a8f25
ME
2994 u8 stopped_ok;
2995};
2996
2997#define XMON_NUM_SPUS 16 /* Enough for current hardware */
2998
2999static struct spu_info spu_info[XMON_NUM_SPUS];
3000
3001void xmon_register_spus(struct list_head *list)
3002{
3003 struct spu *spu;
3004
3005 list_for_each_entry(spu, list, full_list) {
3006 if (spu->number >= XMON_NUM_SPUS) {
3007 WARN_ON(1);
3008 continue;
3009 }
3010
3011 spu_info[spu->number].spu = spu;
3012 spu_info[spu->number].stopped_ok = 0;
24a24c85
ME
3013 spu_info[spu->number].dump_addr = (unsigned long)
3014 spu_info[spu->number].spu->local_store;
ff8a8f25
ME
3015 }
3016}
3017
3018static void stop_spus(void)
3019{
3020 struct spu *spu;
3021 int i;
3022 u64 tmp;
3023
3024 for (i = 0; i < XMON_NUM_SPUS; i++) {
3025 if (!spu_info[i].spu)
3026 continue;
3027
3028 if (setjmp(bus_error_jmp) == 0) {
3029 catch_memory_errors = 1;
3030 sync();
3031
3032 spu = spu_info[i].spu;
3033
3034 spu_info[i].saved_spu_runcntl_RW =
3035 in_be32(&spu->problem->spu_runcntl_RW);
3036
3037 tmp = spu_mfc_sr1_get(spu);
3038 spu_info[i].saved_mfc_sr1_RW = tmp;
3039
3040 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3041 spu_mfc_sr1_set(spu, tmp);
3042
3043 sync();
3044 __delay(200);
3045
3046 spu_info[i].stopped_ok = 1;
2a14442b
ME
3047
3048 printf("Stopped spu %.2d (was %s)\n", i,
3049 spu_info[i].saved_spu_runcntl_RW ?
3050 "running" : "stopped");
ff8a8f25
ME
3051 } else {
3052 catch_memory_errors = 0;
3053 printf("*** Error stopping spu %.2d\n", i);
3054 }
3055 catch_memory_errors = 0;
3056 }
3057}
3058
3059static void restart_spus(void)
3060{
3061 struct spu *spu;
3062 int i;
3063
3064 for (i = 0; i < XMON_NUM_SPUS; i++) {
3065 if (!spu_info[i].spu)
3066 continue;
3067
3068 if (!spu_info[i].stopped_ok) {
3069 printf("*** Error, spu %d was not successfully stopped"
3070 ", not restarting\n", i);
3071 continue;
3072 }
3073
3074 if (setjmp(bus_error_jmp) == 0) {
3075 catch_memory_errors = 1;
3076 sync();
3077
3078 spu = spu_info[i].spu;
3079 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3080 out_be32(&spu->problem->spu_runcntl_RW,
3081 spu_info[i].saved_spu_runcntl_RW);
3082
3083 sync();
3084 __delay(200);
3085
3086 printf("Restarted spu %.2d\n", i);
3087 } else {
3088 catch_memory_errors = 0;
3089 printf("*** Error restarting spu %.2d\n", i);
3090 }
3091 catch_memory_errors = 0;
3092 }
3093}
3094
a8984970 3095#define DUMP_WIDTH 23
437a0706 3096#define DUMP_VALUE(format, field, value) \
a8984970
ME
3097do { \
3098 if (setjmp(bus_error_jmp) == 0) { \
3099 catch_memory_errors = 1; \
3100 sync(); \
3101 printf(" %-*s = "format"\n", DUMP_WIDTH, \
437a0706 3102 #field, value); \
a8984970
ME
3103 sync(); \
3104 __delay(200); \
3105 } else { \
3106 catch_memory_errors = 0; \
3107 printf(" %-*s = *** Error reading field.\n", \
3108 DUMP_WIDTH, #field); \
3109 } \
3110 catch_memory_errors = 0; \
3111} while (0)
3112
437a0706
ME
3113#define DUMP_FIELD(obj, format, field) \
3114 DUMP_VALUE(format, field, obj->field)
3115
a8984970
ME
3116static void dump_spu_fields(struct spu *spu)
3117{
3118 printf("Dumping spu fields at address %p:\n", spu);
3119
3120 DUMP_FIELD(spu, "0x%x", number);
3121 DUMP_FIELD(spu, "%s", name);
a8984970
ME
3122 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3123 DUMP_FIELD(spu, "0x%p", local_store);
3124 DUMP_FIELD(spu, "0x%lx", ls_size);
3125 DUMP_FIELD(spu, "0x%x", node);
3126 DUMP_FIELD(spu, "0x%lx", flags);
a8984970 3127 DUMP_FIELD(spu, "%d", class_0_pending);
f3d69e05 3128 DUMP_FIELD(spu, "0x%lx", class_0_dar);
f3d69e05
LB
3129 DUMP_FIELD(spu, "0x%lx", class_1_dar);
3130 DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
a8984970
ME
3131 DUMP_FIELD(spu, "0x%lx", irqs[0]);
3132 DUMP_FIELD(spu, "0x%lx", irqs[1]);
3133 DUMP_FIELD(spu, "0x%lx", irqs[2]);
3134 DUMP_FIELD(spu, "0x%x", slb_replace);
3135 DUMP_FIELD(spu, "%d", pid);
a8984970
ME
3136 DUMP_FIELD(spu, "0x%p", mm);
3137 DUMP_FIELD(spu, "0x%p", ctx);
3138 DUMP_FIELD(spu, "0x%p", rq);
3139 DUMP_FIELD(spu, "0x%p", timestamp);
3140 DUMP_FIELD(spu, "0x%lx", problem_phys);
3141 DUMP_FIELD(spu, "0x%p", problem);
437a0706
ME
3142 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3143 in_be32(&spu->problem->spu_runcntl_RW));
3144 DUMP_VALUE("0x%x", problem->spu_status_R,
3145 in_be32(&spu->problem->spu_status_R));
3146 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3147 in_be32(&spu->problem->spu_npc_RW));
a8984970 3148 DUMP_FIELD(spu, "0x%p", priv2);
a985239b 3149 DUMP_FIELD(spu, "0x%p", pdata);
a8984970
ME
3150}
3151
af89fb80
ME
3152int
3153spu_inst_dump(unsigned long adr, long count, int praddr)
3154{
3155 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3156}
3157
3158static void dump_spu_ls(unsigned long num, int subcmd)
24a24c85
ME
3159{
3160 unsigned long offset, addr, ls_addr;
3161
3162 if (setjmp(bus_error_jmp) == 0) {
3163 catch_memory_errors = 1;
3164 sync();
3165 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3166 sync();
3167 __delay(200);
3168 } else {
3169 catch_memory_errors = 0;
3170 printf("*** Error: accessing spu info for spu %d\n", num);
3171 return;
3172 }
3173 catch_memory_errors = 0;
3174
3175 if (scanhex(&offset))
3176 addr = ls_addr + offset;
3177 else
3178 addr = spu_info[num].dump_addr;
3179
3180 if (addr >= ls_addr + LS_SIZE) {
3181 printf("*** Error: address outside of local store\n");
3182 return;
3183 }
3184
af89fb80
ME
3185 switch (subcmd) {
3186 case 'i':
3187 addr += spu_inst_dump(addr, 16, 1);
3188 last_cmd = "sdi\n";
3189 break;
3190 default:
3191 prdump(addr, 64);
3192 addr += 64;
3193 last_cmd = "sd\n";
3194 break;
3195 }
24a24c85
ME
3196
3197 spu_info[num].dump_addr = addr;
3198}
3199
ff8a8f25
ME
3200static int do_spu_cmd(void)
3201{
24a24c85 3202 static unsigned long num = 0;
af89fb80 3203 int cmd, subcmd = 0;
ff8a8f25
ME
3204
3205 cmd = inchar();
3206 switch (cmd) {
3207 case 's':
3208 stop_spus();
3209 break;
3210 case 'r':
3211 restart_spus();
3212 break;
24a24c85 3213 case 'd':
af89fb80
ME
3214 subcmd = inchar();
3215 if (isxdigit(subcmd) || subcmd == '\n')
3216 termch = subcmd;
3217 case 'f':
24a24c85
ME
3218 scanhex(&num);
3219 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
a8984970 3220 printf("*** Error: invalid spu number\n");
24a24c85
ME
3221 return 0;
3222 }
3223
3224 switch (cmd) {
3225 case 'f':
3226 dump_spu_fields(spu_info[num].spu);
3227 break;
3228 default:
af89fb80 3229 dump_spu_ls(num, subcmd);
24a24c85
ME
3230 break;
3231 }
3232
a8984970 3233 break;
ff8a8f25
ME
3234 default:
3235 return -1;
3236 }
3237
3238 return 0;
3239}
e055595d 3240#else /* ! CONFIG_SPU_BASE */
ff8a8f25
ME
3241static int do_spu_cmd(void)
3242{
3243 return -1;
3244}
3245#endif