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