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