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