Merge tag 'hsi-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi
[linux-2.6-block.git] / arch / powerpc / xmon / xmon.c
CommitLineData
1da177e4
LT
1/*
2 * Routines providing a simple monitor for use on the PowerMac.
3 *
fca5dcd4 4 * Copyright (C) 1996-2005 Paul Mackerras.
47679283
ME
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
1da177e4
LT
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
56144ec7
ME
13
14#include <linux/kernel.h>
1da177e4 15#include <linux/errno.h>
3f07c014 16#include <linux/sched/signal.h>
1da177e4
LT
17#include <linux/smp.h>
18#include <linux/mm.h>
19#include <linux/reboot.h>
20#include <linux/delay.h>
21#include <linux/kallsyms.h>
ca5dd395 22#include <linux/kmsg_dump.h>
1da177e4 23#include <linux/cpumask.h>
4b16f8e2 24#include <linux/export.h>
fca5dcd4 25#include <linux/sysrq.h>
4694ca02 26#include <linux/interrupt.h>
7d12e780 27#include <linux/irq.h>
73c9ceab 28#include <linux/bug.h>
a71d64b4 29#include <linux/nmi.h>
05b981f4 30#include <linux/ctype.h>
80eff6c4 31#include <linux/highmem.h>
1da177e4 32
7644d581 33#include <asm/debugfs.h>
1da177e4 34#include <asm/ptrace.h>
243e2511 35#include <asm/smp.h>
1da177e4
LT
36#include <asm/string.h>
37#include <asm/prom.h>
38#include <asm/machdep.h>
f78541dc 39#include <asm/xmon.h>
1da177e4
LT
40#include <asm/processor.h>
41#include <asm/pgtable.h>
42#include <asm/mmu.h>
43#include <asm/mmu_context.h>
ab83dc79 44#include <asm/plpar_wrappers.h>
1da177e4
LT
45#include <asm/cputable.h>
46#include <asm/rtas.h>
47#include <asm/sstep.h>
f583ffce 48#include <asm/irq_regs.h>
ff8a8f25
ME
49#include <asm/spu.h>
50#include <asm/spu_priv1.h>
c3b75bd7 51#include <asm/setjmp.h>
322b4394 52#include <asm/reg.h>
ae3a197e 53#include <asm/debug.h>
9422de3e 54#include <asm/hw_breakpoint.h>
243e2511 55#include <asm/xive.h>
fde93a0f
AD
56#include <asm/opal.h>
57#include <asm/firmware.h>
efe4fbb1 58#include <asm/code-patching.h>
fde93a0f 59
f78541dc 60#ifdef CONFIG_PPC64
1da177e4 61#include <asm/hvcall.h>
f78541dc
PM
62#include <asm/paca.h>
63#endif
1da177e4
LT
64
65#include "nonstdio.h"
e0426047 66#include "dis-asm.h"
1da177e4 67
1da177e4 68#ifdef CONFIG_SMP
1c8950ff 69static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
1da177e4
LT
70static unsigned long xmon_taken = 1;
71static int xmon_owner;
72static int xmon_gate;
ddadb6b8
ME
73#else
74#define xmon_owner 0
1da177e4
LT
75#endif /* CONFIG_SMP */
76
5be3492f 77static unsigned long in_xmon __read_mostly = 0;
3b5bf42b 78static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
1da177e4
LT
79
80static unsigned long adrs;
81static int size = 1;
82#define MAX_DUMP (128 * 1024)
83static unsigned long ndump = 64;
84static unsigned long nidump = 16;
85static unsigned long ncsum = 4096;
86static int termch;
87static char tmpstr[128];
ed49f7fd 88static int tracing_enabled;
1da177e4 89
1da177e4
LT
90static long bus_error_jmp[JMP_BUF_LEN];
91static int catch_memory_errors;
31cdd0c3 92static int catch_spr_faults;
1da177e4 93static long *xmon_fault_jmp[NR_CPUS];
1da177e4
LT
94
95/* Breakpoint stuff */
96struct bpt {
97 unsigned long address;
98 unsigned int instr[2];
99 atomic_t ref_count;
100 int enabled;
101 unsigned long pad;
102};
103
104/* Bits in bpt.enabled */
abb90ee7
ME
105#define BP_CIABR 1
106#define BP_TRAP 2
107#define BP_DABR 4
1da177e4
LT
108
109#define NBPTS 256
110static struct bpt bpts[NBPTS];
111static struct bpt dabr;
112static struct bpt *iabr;
113static unsigned bpinstr = 0x7fe00008; /* trap */
114
115#define BP_NUM(bp) ((bp) - bpts + 1)
116
117/* Prototypes */
118static int cmds(struct pt_regs *);
119static int mread(unsigned long, void *, int);
120static int mwrite(unsigned long, void *, int);
121static int handle_fault(struct pt_regs *);
122static void byterev(unsigned char *, int);
123static void memex(void);
124static int bsesc(void);
125static void dump(void);
80eff6c4 126static void show_pte(unsigned long);
1da177e4
LT
127static void prdump(unsigned long, long);
128static int ppc_inst_dump(unsigned long, long, int);
f312deb4 129static void dump_log_buf(void);
fde93a0f
AD
130
131#ifdef CONFIG_PPC_POWERNV
132static void dump_opal_msglog(void);
133#else
134static inline void dump_opal_msglog(void)
135{
136 printf("Machine is not running OPAL firmware.\n");
137}
138#endif
139
1da177e4
LT
140static void backtrace(struct pt_regs *);
141static void excprint(struct pt_regs *);
142static void prregs(struct pt_regs *);
143static void memops(int);
144static void memlocate(void);
145static void memzcan(void);
146static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
147int skipbl(void);
148int scanhex(unsigned long *valp);
149static void scannl(void);
150static int hexdigit(int);
151void getstring(char *, int);
152static void flush_input(void);
153static int inchar(void);
154static void take_input(char *);
31cdd0c3 155static int read_spr(int, unsigned long *);
1da177e4
LT
156static void write_spr(int, unsigned long);
157static void super_regs(void);
158static void remove_bpts(void);
159static void insert_bpts(void);
160static void remove_cpu_bpts(void);
161static void insert_cpu_bpts(void);
162static struct bpt *at_breakpoint(unsigned long pc);
163static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
164static int do_step(struct pt_regs *);
165static void bpt_cmds(void);
166static void cacheflush(void);
167static int cpu_cmd(void);
168static void csum(void);
169static void bootcmds(void);
f78541dc 170static void proccall(void);
6dfb5404 171static void show_tasks(void);
1da177e4
LT
172void dump_segments(void);
173static void symbol_lookup(void);
26c8af5f
OH
174static void xmon_show_stack(unsigned long sp, unsigned long lr,
175 unsigned long pc);
1da177e4
LT
176static void xmon_print_symbol(unsigned long address, const char *mid,
177 const char *after);
178static const char *getvecname(unsigned long vec);
179
ff8a8f25
ME
180static int do_spu_cmd(void);
181
5a8a1a28
BH
182#ifdef CONFIG_44x
183static void dump_tlb_44x(void);
184#endif
03247157
BH
185#ifdef CONFIG_PPC_BOOK3E
186static void dump_tlb_book3e(void);
187#endif
5a8a1a28 188
f78541dc
PM
189#ifdef CONFIG_PPC64
190#define REG "%.16lx"
f78541dc
PM
191#else
192#define REG "%.8lx"
f78541dc 193#endif
1da177e4 194
72eceef6
PB
195#ifdef __LITTLE_ENDIAN__
196#define GETWORD(v) (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
197#else
1da177e4 198#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
72eceef6 199#endif
1da177e4 200
1da177e4
LT
201static char *help_string = "\
202Commands:\n\
203 b show breakpoints\n\
204 bd set data breakpoint\n\
205 bi set instruction breakpoint\n\
206 bc clear breakpoint\n"
207#ifdef CONFIG_SMP
208 "\
209 c print cpus stopped in xmon\n\
210 c# try to switch to cpu number h (in hex)\n"
211#endif
212 "\
213 C checksum\n\
214 d dump bytes\n\
5e48dc0a
DM
215 d1 dump 1 byte values\n\
216 d2 dump 2 byte values\n\
217 d4 dump 4 byte values\n\
218 d8 dump 8 byte values\n\
1da177e4
LT
219 di dump instructions\n\
220 df dump float values\n\
221 dd dump double values\n\
ddadb6b8 222 dl dump the kernel log buffer\n"
fde93a0f
AD
223#ifdef CONFIG_PPC_POWERNV
224 "\
225 do dump the OPAL message log\n"
226#endif
ddadb6b8
ME
227#ifdef CONFIG_PPC64
228 "\
229 dp[#] dump paca for current cpu, or cpu #\n\
230 dpa dump paca for all possible cpus\n"
231#endif
232 "\
7e5b5938 233 dr dump stream of raw bytes\n\
80eff6c4 234 dv dump virtual address translation \n\
56144ec7 235 dt dump the tracing buffers (uses printk)\n\
4125d012 236 dtc dump the tracing buffers for current CPU (uses printk)\n\
243e2511
BH
237"
238#ifdef CONFIG_PPC_POWERNV
239" dx# dump xive on CPU #\n\
240 dxi# dump xive irq state #\n\
241 dxa dump xive on all CPUs\n"
242#endif
243" e print exception information\n\
1da177e4
LT
244 f flush cache\n\
245 la lookup symbol+offset of specified address\n\
246 ls lookup address of specified symbol\n\
247 m examine/change memory\n\
248 mm move a block of memory\n\
249 ms set a block of memory\n\
250 md compare two blocks of memory\n\
251 ml locate a block of memory\n\
252 mz zero a block of memory\n\
253 mi show information about memory allocation\n\
f78541dc 254 p call a procedure\n\
6dfb5404 255 P list processes/tasks\n\
1da177e4 256 r print registers\n\
ff8a8f25 257 s single step\n"
e055595d 258#ifdef CONFIG_SPU_BASE
ff8a8f25 259" ss stop execution on all spus\n\
a8984970 260 sr restore execution on stopped spus\n\
24a24c85 261 sf # dump spu fields for spu # (in hex)\n\
c99176a2 262 sd # dump spu local store for spu # (in hex)\n\
af89fb80 263 sdi # disassemble spu local store for spu # (in hex)\n"
ff8a8f25
ME
264#endif
265" S print special registers\n\
31cdd0c3
PM
266 Sa print all SPRs\n\
267 Sr # read SPR #\n\
268 Sw #v write v to SPR #\n\
1da177e4 269 t print backtrace\n\
1da177e4 270 x exit monitor and recover\n\
2e340579 271 X exit monitor and don't recover\n"
79873e8d 272#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
f78541dc 273" u dump segment table or SLB\n"
79873e8d 274#elif defined(CONFIG_PPC_STD_MMU_32)
f78541dc 275" u dump segment registers\n"
79873e8d 276#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
5a8a1a28
BH
277" u dump TLB\n"
278#endif
59d3391e 279" U show uptime information\n"
f78541dc 280" ? help\n"
0c23a88c 281" # n limit output to n lines per page (for dp, dpa, dl)\n"
f78541dc 282" zr reboot\n\
1da177e4
LT
283 zh halt\n"
284;
285
286static struct pt_regs *xmon_regs;
287
f78541dc 288static inline void sync(void)
1da177e4
LT
289{
290 asm volatile("sync; isync");
291}
292
f78541dc
PM
293static inline void store_inst(void *p)
294{
295 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
296}
297
298static inline void cflush(void *p)
299{
300 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
301}
302
303static inline void cinval(void *p)
304{
305 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
306}
1da177e4 307
1ad7d705
AK
308/**
309 * write_ciabr() - write the CIABR SPR
310 * @ciabr: The value to write.
311 *
312 * This function writes a value to the CIARB register either directly
313 * through mtspr instruction if the kernel is in HV privilege mode or
314 * call a hypervisor function to achieve the same in case the kernel
315 * is in supervisor privilege mode.
316 */
317static void write_ciabr(unsigned long ciabr)
318{
319 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
320 return;
321
322 if (cpu_has_feature(CPU_FTR_HVMODE)) {
323 mtspr(SPRN_CIABR, ciabr);
324 return;
325 }
7c09c186 326 plpar_set_ciabr(ciabr);
1ad7d705
AK
327}
328
329/**
330 * set_ciabr() - set the CIABR
331 * @addr: The value to set.
332 *
333 * This function sets the correct privilege value into the the HW
334 * breakpoint address before writing it up in the CIABR register.
335 */
336static void set_ciabr(unsigned long addr)
337{
338 addr &= ~CIABR_PRIV;
339
340 if (cpu_has_feature(CPU_FTR_HVMODE))
341 addr |= CIABR_PRIV_HYPER;
342 else
343 addr |= CIABR_PRIV_SUPER;
344 write_ciabr(addr);
345}
346
1da177e4
LT
347/*
348 * Disable surveillance (the service processor watchdog function)
349 * while we are in xmon.
350 * XXX we should re-enable it when we leave. :)
351 */
352#define SURVEILLANCE_TOKEN 9000
353
354static inline void disable_surveillance(void)
355{
356#ifdef CONFIG_PPC_PSERIES
357 /* Since this can't be a module, args should end up below 4GB. */
358 static struct rtas_args args;
08eb105a 359 int token;
1da177e4
LT
360
361 /*
362 * At this point we have got all the cpus we can into
363 * xmon, so there is hopefully no other cpu calling RTAS
364 * at the moment, even though we don't take rtas.lock.
365 * If we did try to take rtas.lock there would be a
366 * real possibility of deadlock.
367 */
08eb105a
ME
368 token = rtas_token("set-indicator");
369 if (token == RTAS_UNKNOWN_SERVICE)
1da177e4 370 return;
08eb105a
ME
371
372 rtas_call_unlocked(&args, token, 3, 1, NULL, SURVEILLANCE_TOKEN, 0, 0);
373
1da177e4
LT
374#endif /* CONFIG_PPC_PSERIES */
375}
376
377#ifdef CONFIG_SMP
378static int xmon_speaker;
379
380static void get_output_lock(void)
381{
382 int me = smp_processor_id() + 0x100;
383 int last_speaker = 0, prev;
384 long timeout;
385
386 if (xmon_speaker == me)
387 return;
730efb61 388
1da177e4 389 for (;;) {
730efb61
ME
390 last_speaker = cmpxchg(&xmon_speaker, 0, me);
391 if (last_speaker == 0)
392 return;
393
15075897
ME
394 /*
395 * Wait a full second for the lock, we might be on a slow
396 * console, but check every 100us.
397 */
398 timeout = 10000;
1da177e4 399 while (xmon_speaker == last_speaker) {
15075897
ME
400 if (--timeout > 0) {
401 udelay(100);
1da177e4 402 continue;
15075897
ME
403 }
404
1da177e4
LT
405 /* hostile takeover */
406 prev = cmpxchg(&xmon_speaker, last_speaker, me);
407 if (prev == last_speaker)
408 return;
409 break;
410 }
411 }
412}
413
414static void release_output_lock(void)
415{
416 xmon_speaker = 0;
417}
1c8950ff
ME
418
419int cpus_are_in_xmon(void)
420{
104699c0 421 return !cpumask_empty(&cpus_in_xmon);
1c8950ff 422}
1cd6ed7c
NP
423
424static bool wait_for_other_cpus(int ncpus)
425{
426 unsigned long timeout;
427
428 /* We wait for 2s, which is a metric "little while" */
429 for (timeout = 20000; timeout != 0; --timeout) {
430 if (cpumask_weight(&cpus_in_xmon) >= ncpus)
431 return true;
432 udelay(100);
433 barrier();
434 }
435
436 return false;
437}
438#endif /* CONFIG_SMP */
1da177e4 439
daf8f403
JB
440static inline int unrecoverable_excp(struct pt_regs *regs)
441{
08f6d6ab 442#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
66857b3a 443 /* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
daf8f403
JB
444 return 0;
445#else
446 return ((regs->msr & MSR_RI) == 0);
447#endif
448}
449
b0da9856 450static int xmon_core(struct pt_regs *regs, int fromipi)
1da177e4
LT
451{
452 int cmd = 0;
1da177e4
LT
453 struct bpt *bp;
454 long recurse_jmp[JMP_BUF_LEN];
455 unsigned long offset;
f13659e0 456 unsigned long flags;
1da177e4
LT
457#ifdef CONFIG_SMP
458 int cpu;
459 int secondary;
1da177e4
LT
460#endif
461
f13659e0 462 local_irq_save(flags);
a71d64b4 463 hard_irq_disable();
1da177e4 464
ed49f7fd
BL
465 tracing_enabled = tracing_is_on();
466 tracing_off();
467
1da177e4
LT
468 bp = in_breakpoint_table(regs->nip, &offset);
469 if (bp != NULL) {
470 regs->nip = bp->address + offset;
471 atomic_dec(&bp->ref_count);
472 }
473
474 remove_cpu_bpts();
475
476#ifdef CONFIG_SMP
477 cpu = smp_processor_id();
104699c0 478 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
31cdd0c3
PM
479 /*
480 * We catch SPR read/write faults here because the 0x700, 0xf60
481 * etc. handlers don't call debugger_fault_handler().
482 */
483 if (catch_spr_faults)
484 longjmp(bus_error_jmp, 1);
1da177e4
LT
485 get_output_lock();
486 excprint(regs);
487 printf("cpu 0x%x: Exception %lx %s in xmon, "
488 "returning to main loop\n",
489 cpu, regs->trap, getvecname(TRAP(regs)));
5cb4cc0d 490 release_output_lock();
1da177e4
LT
491 longjmp(xmon_fault_jmp[cpu], 1);
492 }
493
494 if (setjmp(recurse_jmp) != 0) {
495 if (!in_xmon || !xmon_gate) {
5cb4cc0d 496 get_output_lock();
1da177e4
LT
497 printf("xmon: WARNING: bad recursive fault "
498 "on cpu 0x%x\n", cpu);
5cb4cc0d 499 release_output_lock();
1da177e4
LT
500 goto waiting;
501 }
502 secondary = !(xmon_taken && cpu == xmon_owner);
503 goto cmdloop;
504 }
505
506 xmon_fault_jmp[cpu] = recurse_jmp;
1da177e4
LT
507
508 bp = NULL;
9f0b0793 509 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
1da177e4 510 bp = at_breakpoint(regs->nip);
daf8f403 511 if (bp || unrecoverable_excp(regs))
1da177e4
LT
512 fromipi = 0;
513
514 if (!fromipi) {
515 get_output_lock();
516 excprint(regs);
517 if (bp) {
e70d8f55 518 printf("cpu 0x%x stopped at breakpoint 0x%tx (",
1da177e4
LT
519 cpu, BP_NUM(bp));
520 xmon_print_symbol(regs->nip, " ", ")\n");
521 }
daf8f403 522 if (unrecoverable_excp(regs))
1da177e4
LT
523 printf("WARNING: exception is not recoverable, "
524 "can't continue\n");
525 release_output_lock();
526 }
527
d2b496e5
ME
528 cpumask_set_cpu(cpu, &cpus_in_xmon);
529
1da177e4
LT
530 waiting:
531 secondary = 1;
064996d6 532 spin_begin();
1da177e4
LT
533 while (secondary && !xmon_gate) {
534 if (in_xmon == 0) {
064996d6
NP
535 if (fromipi) {
536 spin_end();
1da177e4 537 goto leave;
064996d6 538 }
1da177e4
LT
539 secondary = test_and_set_bit(0, &in_xmon);
540 }
064996d6
NP
541 spin_cpu_relax();
542 touch_nmi_watchdog();
1da177e4 543 }
064996d6 544 spin_end();
1da177e4
LT
545
546 if (!secondary && !xmon_gate) {
547 /* we are the first cpu to come in */
548 /* interrupt other cpu(s) */
549 int ncpus = num_online_cpus();
550
551 xmon_owner = cpu;
552 mb();
553 if (ncpus > 1) {
1cd6ed7c
NP
554 /*
555 * A system reset (trap == 0x100) can be triggered on
556 * all CPUs, so when we come in via 0x100 try waiting
557 * for the other CPUs to come in before we send the
558 * debugger break (IPI). This is similar to
559 * crash_kexec_secondary().
560 */
561 if (TRAP(regs) != 0x100 || !wait_for_other_cpus(ncpus))
562 smp_send_debugger_break();
563
564 wait_for_other_cpus(ncpus);
1da177e4
LT
565 }
566 remove_bpts();
567 disable_surveillance();
568 /* for breakpoint or single step, print the current instr. */
569 if (bp || TRAP(regs) == 0xd00)
570 ppc_inst_dump(regs->nip, 1, 0);
571 printf("enter ? for help\n");
572 mb();
573 xmon_gate = 1;
574 barrier();
064996d6 575 touch_nmi_watchdog();
1da177e4
LT
576 }
577
578 cmdloop:
579 while (in_xmon) {
580 if (secondary) {
064996d6 581 spin_begin();
1da177e4
LT
582 if (cpu == xmon_owner) {
583 if (!test_and_set_bit(0, &xmon_taken)) {
584 secondary = 0;
064996d6 585 spin_end();
1da177e4
LT
586 continue;
587 }
588 /* missed it */
589 while (cpu == xmon_owner)
064996d6 590 spin_cpu_relax();
1da177e4 591 }
064996d6
NP
592 spin_cpu_relax();
593 touch_nmi_watchdog();
1da177e4
LT
594 } else {
595 cmd = cmds(regs);
596 if (cmd != 0) {
597 /* exiting xmon */
598 insert_bpts();
599 xmon_gate = 0;
600 wmb();
601 in_xmon = 0;
602 break;
603 }
604 /* have switched to some other cpu */
605 secondary = 1;
606 }
607 }
608 leave:
104699c0 609 cpumask_clear_cpu(cpu, &cpus_in_xmon);
1da177e4 610 xmon_fault_jmp[cpu] = NULL;
1da177e4
LT
611#else
612 /* UP is simple... */
613 if (in_xmon) {
614 printf("Exception %lx %s in xmon, returning to main loop\n",
615 regs->trap, getvecname(TRAP(regs)));
616 longjmp(xmon_fault_jmp[0], 1);
617 }
618 if (setjmp(recurse_jmp) == 0) {
619 xmon_fault_jmp[0] = recurse_jmp;
620 in_xmon = 1;
621
622 excprint(regs);
623 bp = at_breakpoint(regs->nip);
624 if (bp) {
e70d8f55 625 printf("Stopped at breakpoint %tx (", BP_NUM(bp));
1da177e4
LT
626 xmon_print_symbol(regs->nip, " ", ")\n");
627 }
daf8f403 628 if (unrecoverable_excp(regs))
1da177e4
LT
629 printf("WARNING: exception is not recoverable, "
630 "can't continue\n");
631 remove_bpts();
632 disable_surveillance();
633 /* for breakpoint or single step, print the current instr. */
634 if (bp || TRAP(regs) == 0xd00)
635 ppc_inst_dump(regs->nip, 1, 0);
636 printf("enter ? for help\n");
637 }
638
639 cmd = cmds(regs);
640
641 insert_bpts();
642 in_xmon = 0;
643#endif
644
cdd3904d
JB
645#ifdef CONFIG_BOOKE
646 if (regs->msr & MSR_DE) {
647 bp = at_breakpoint(regs->nip);
648 if (bp != NULL) {
649 regs->nip = (unsigned long) &bp->instr[0];
650 atomic_inc(&bp->ref_count);
651 }
652 }
653#else
9f0b0793 654 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
1da177e4
LT
655 bp = at_breakpoint(regs->nip);
656 if (bp != NULL) {
657 int stepped = emulate_step(regs, bp->instr[0]);
658 if (stepped == 0) {
659 regs->nip = (unsigned long) &bp->instr[0];
660 atomic_inc(&bp->ref_count);
661 } else if (stepped < 0) {
662 printf("Couldn't single-step %s instruction\n",
663 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
664 }
665 }
666 }
cdd3904d 667#endif
1da177e4
LT
668 insert_cpu_bpts();
669
a71d64b4 670 touch_nmi_watchdog();
f13659e0 671 local_irq_restore(flags);
1da177e4 672
0a730ae5 673 return cmd != 'X' && cmd != EOF;
1da177e4
LT
674}
675
676int xmon(struct pt_regs *excp)
677{
678 struct pt_regs regs;
679
680 if (excp == NULL) {
322b4394 681 ppc_save_regs(&regs);
1da177e4
LT
682 excp = &regs;
683 }
ff8a8f25 684
1da177e4
LT
685 return xmon_core(excp, 0);
686}
f78541dc
PM
687EXPORT_SYMBOL(xmon);
688
f583ffce 689irqreturn_t xmon_irq(int irq, void *d)
f78541dc
PM
690{
691 unsigned long flags;
692 local_irq_save(flags);
693 printf("Keyboard interrupt\n");
f583ffce 694 xmon(get_irq_regs());
f78541dc
PM
695 local_irq_restore(flags);
696 return IRQ_HANDLED;
697}
1da177e4 698
b0da9856 699static int xmon_bpt(struct pt_regs *regs)
1da177e4
LT
700{
701 struct bpt *bp;
702 unsigned long offset;
703
9f0b0793 704 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4
LT
705 return 0;
706
707 /* Are we at the trap at bp->instr[1] for some bp? */
708 bp = in_breakpoint_table(regs->nip, &offset);
709 if (bp != NULL && offset == 4) {
710 regs->nip = bp->address + 4;
711 atomic_dec(&bp->ref_count);
712 return 1;
713 }
714
715 /* Are we at a breakpoint? */
716 bp = at_breakpoint(regs->nip);
717 if (!bp)
718 return 0;
719
720 xmon_core(regs, 0);
721
722 return 1;
723}
724
b0da9856 725static int xmon_sstep(struct pt_regs *regs)
1da177e4
LT
726{
727 if (user_mode(regs))
728 return 0;
729 xmon_core(regs, 0);
730 return 1;
731}
732
9422de3e 733static int xmon_break_match(struct pt_regs *regs)
1da177e4 734{
9f0b0793 735 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4 736 return 0;
fd9648df
AB
737 if (dabr.enabled == 0)
738 return 0;
1da177e4
LT
739 xmon_core(regs, 0);
740 return 1;
741}
742
b0da9856 743static int xmon_iabr_match(struct pt_regs *regs)
1da177e4 744{
9f0b0793 745 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
1da177e4 746 return 0;
9f1067c2 747 if (iabr == NULL)
1da177e4
LT
748 return 0;
749 xmon_core(regs, 0);
750 return 1;
751}
752
b0da9856 753static int xmon_ipi(struct pt_regs *regs)
1da177e4
LT
754{
755#ifdef CONFIG_SMP
104699c0 756 if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
1da177e4
LT
757 xmon_core(regs, 1);
758#endif
759 return 0;
760}
761
b0da9856 762static int xmon_fault_handler(struct pt_regs *regs)
1da177e4
LT
763{
764 struct bpt *bp;
765 unsigned long offset;
766
767 if (in_xmon && catch_memory_errors)
768 handle_fault(regs); /* doesn't return */
769
9f0b0793 770 if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
1da177e4
LT
771 bp = in_breakpoint_table(regs->nip, &offset);
772 if (bp != NULL) {
773 regs->nip = bp->address + offset;
774 atomic_dec(&bp->ref_count);
775 }
776 }
777
778 return 0;
779}
780
7daf5930
MS
781/* Force enable xmon if not already enabled */
782static inline void force_enable_xmon(void)
783{
784 /* Enable xmon hooks if needed */
785 if (!xmon_on) {
786 printf("xmon: Enabling debugger hooks\n");
787 xmon_on = 1;
788 }
789}
790
1da177e4
LT
791static struct bpt *at_breakpoint(unsigned long pc)
792{
793 int i;
794 struct bpt *bp;
795
796 bp = bpts;
797 for (i = 0; i < NBPTS; ++i, ++bp)
798 if (bp->enabled && pc == bp->address)
799 return bp;
800 return NULL;
801}
802
803static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
804{
805 unsigned long off;
806
807 off = nip - (unsigned long) bpts;
808 if (off >= sizeof(bpts))
809 return NULL;
810 off %= sizeof(struct bpt);
811 if (off != offsetof(struct bpt, instr[0])
812 && off != offsetof(struct bpt, instr[1]))
813 return NULL;
814 *offp = off - offsetof(struct bpt, instr[0]);
815 return (struct bpt *) (nip - off);
816}
817
818static struct bpt *new_breakpoint(unsigned long a)
819{
820 struct bpt *bp;
821
822 a &= ~3UL;
823 bp = at_breakpoint(a);
824 if (bp)
825 return bp;
826
827 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
828 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
829 bp->address = a;
830 bp->instr[1] = bpinstr;
831 store_inst(&bp->instr[1]);
832 return bp;
833 }
834 }
835
836 printf("Sorry, no free breakpoints. Please clear one first.\n");
837 return NULL;
838}
839
840static void insert_bpts(void)
841{
842 int i;
843 struct bpt *bp;
844
845 bp = bpts;
846 for (i = 0; i < NBPTS; ++i, ++bp) {
abb90ee7 847 if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0)
1da177e4
LT
848 continue;
849 if (mread(bp->address, &bp->instr[0], 4) != 4) {
850 printf("Couldn't read instruction at %lx, "
851 "disabling breakpoint there\n", bp->address);
852 bp->enabled = 0;
853 continue;
854 }
855 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
856 printf("Breakpoint at %lx is on an mtmsrd or rfid "
857 "instruction, disabling it\n", bp->address);
858 bp->enabled = 0;
859 continue;
860 }
861 store_inst(&bp->instr[0]);
abb90ee7 862 if (bp->enabled & BP_CIABR)
1da177e4 863 continue;
efe4fbb1
BS
864 if (patch_instruction((unsigned int *)bp->address,
865 bpinstr) != 0) {
1da177e4
LT
866 printf("Couldn't write instruction at %lx, "
867 "disabling breakpoint there\n", bp->address);
868 bp->enabled &= ~BP_TRAP;
869 continue;
870 }
871 store_inst((void *)bp->address);
872 }
873}
874
875static void insert_cpu_bpts(void)
876{
9422de3e
MN
877 struct arch_hw_breakpoint brk;
878
879 if (dabr.enabled) {
880 brk.address = dabr.address;
881 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
882 brk.len = 8;
21f58507 883 __set_breakpoint(&brk);
9422de3e 884 }
1ad7d705
AK
885
886 if (iabr)
887 set_ciabr(iabr->address);
1da177e4
LT
888}
889
890static void remove_bpts(void)
891{
892 int i;
893 struct bpt *bp;
894 unsigned instr;
895
896 bp = bpts;
897 for (i = 0; i < NBPTS; ++i, ++bp) {
abb90ee7 898 if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP)
1da177e4
LT
899 continue;
900 if (mread(bp->address, &instr, 4) == 4
901 && instr == bpinstr
efe4fbb1
BS
902 && patch_instruction(
903 (unsigned int *)bp->address, bp->instr[0]) != 0)
1da177e4
LT
904 printf("Couldn't remove breakpoint at %lx\n",
905 bp->address);
906 else
907 store_inst((void *)bp->address);
908 }
909}
910
911static void remove_cpu_bpts(void)
912{
9422de3e 913 hw_breakpoint_disable();
1ad7d705 914 write_ciabr(0);
1da177e4
LT
915}
916
59d3391e
GP
917/* Based on uptime_proc_show(). */
918static void
919show_uptime(void)
920{
921 struct timespec uptime;
922
923 if (setjmp(bus_error_jmp) == 0) {
924 catch_memory_errors = 1;
925 sync();
926
927 get_monotonic_boottime(&uptime);
928 printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
929 ((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
930
931 sync();
932 __delay(200); \
933 }
934 catch_memory_errors = 0;
935}
936
958b7c80
S
937static void set_lpp_cmd(void)
938{
939 unsigned long lpp;
940
941 if (!scanhex(&lpp)) {
942 printf("Invalid number.\n");
943 lpp = 0;
944 }
945 xmon_set_pagination_lpp(lpp);
946}
1da177e4
LT
947/* Command interpreting routine */
948static char *last_cmd;
949
950static int
951cmds(struct pt_regs *excp)
952{
953 int cmd = 0;
954
955 last_cmd = NULL;
956 xmon_regs = excp;
26c8af5f 957
b561783c 958 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
26c8af5f 959
1da177e4
LT
960 for(;;) {
961#ifdef CONFIG_SMP
962 printf("%x:", smp_processor_id());
963#endif /* CONFIG_SMP */
964 printf("mon> ");
1da177e4
LT
965 flush_input();
966 termch = 0;
967 cmd = skipbl();
968 if( cmd == '\n' ) {
969 if (last_cmd == NULL)
970 continue;
971 take_input(last_cmd);
972 last_cmd = NULL;
973 cmd = inchar();
974 }
975 switch (cmd) {
976 case 'm':
977 cmd = inchar();
978 switch (cmd) {
979 case 'm':
980 case 's':
981 case 'd':
982 memops(cmd);
983 break;
984 case 'l':
985 memlocate();
986 break;
987 case 'z':
988 memzcan();
989 break;
990 case 'i':
9af744d7 991 show_mem(0, NULL);
1da177e4
LT
992 break;
993 default:
994 termch = cmd;
995 memex();
996 }
997 break;
998 case 'd':
999 dump();
1000 break;
1001 case 'l':
1002 symbol_lookup();
1003 break;
1004 case 'r':
1005 prregs(excp); /* print regs */
1006 break;
1007 case 'e':
1008 excprint(excp);
1009 break;
1010 case 'S':
1011 super_regs();
1012 break;
1013 case 't':
1014 backtrace(excp);
1015 break;
1016 case 'f':
1017 cacheflush();
1018 break;
1019 case 's':
ff8a8f25
ME
1020 if (do_spu_cmd() == 0)
1021 break;
1da177e4
LT
1022 if (do_step(excp))
1023 return cmd;
1024 break;
1025 case 'x':
1026 case 'X':
ed49f7fd
BL
1027 if (tracing_enabled)
1028 tracing_on();
bb6b9b28 1029 return cmd;
1da177e4 1030 case EOF:
bb6b9b28
BH
1031 printf(" <no input ...>\n");
1032 mdelay(2000);
1da177e4
LT
1033 return cmd;
1034 case '?':
4d404edc 1035 xmon_puts(help_string);
1da177e4 1036 break;
958b7c80
S
1037 case '#':
1038 set_lpp_cmd();
1039 break;
1da177e4
LT
1040 case 'b':
1041 bpt_cmds();
1042 break;
1043 case 'C':
1044 csum();
1045 break;
1046 case 'c':
1047 if (cpu_cmd())
1048 return 0;
1049 break;
1050 case 'z':
1051 bootcmds();
1052 break;
f78541dc
PM
1053 case 'p':
1054 proccall();
1da177e4 1055 break;
6dfb5404
DM
1056 case 'P':
1057 show_tasks();
1058 break;
f78541dc 1059#ifdef CONFIG_PPC_STD_MMU
1da177e4
LT
1060 case 'u':
1061 dump_segments();
1062 break;
d8ee6f34 1063#elif defined(CONFIG_44x)
5a8a1a28
BH
1064 case 'u':
1065 dump_tlb_44x();
1066 break;
79873e8d 1067#elif defined(CONFIG_PPC_BOOK3E)
03247157
BH
1068 case 'u':
1069 dump_tlb_book3e();
1070 break;
f78541dc 1071#endif
59d3391e
GP
1072 case 'U':
1073 show_uptime();
1074 break;
1da177e4
LT
1075 default:
1076 printf("Unrecognized command: ");
e3bc8049 1077 do {
1da177e4
LT
1078 if (' ' < cmd && cmd <= '~')
1079 putchar(cmd);
1080 else
1081 printf("\\x%x", cmd);
1082 cmd = inchar();
e3bc8049 1083 } while (cmd != '\n');
1da177e4
LT
1084 printf(" (type ? for help)\n");
1085 break;
1086 }
1087 }
1088}
1089
cdd3904d
JB
1090#ifdef CONFIG_BOOKE
1091static int do_step(struct pt_regs *regs)
1092{
1093 regs->msr |= MSR_DE;
1094 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
1095 return 1;
1096}
1097#else
1da177e4
LT
1098/*
1099 * Step a single instruction.
1100 * Some instructions we emulate, others we execute with MSR_SE set.
1101 */
1102static int do_step(struct pt_regs *regs)
1103{
1104 unsigned int instr;
1105 int stepped;
1106
7daf5930 1107 force_enable_xmon();
1da177e4 1108 /* check we are in 64-bit kernel mode, translation enabled */
9f0b0793 1109 if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
1da177e4
LT
1110 if (mread(regs->nip, &instr, 4) == 4) {
1111 stepped = emulate_step(regs, instr);
1112 if (stepped < 0) {
1113 printf("Couldn't single-step %s instruction\n",
1114 (IS_RFID(instr)? "rfid": "mtmsrd"));
1115 return 0;
1116 }
1117 if (stepped > 0) {
1118 regs->trap = 0xd00 | (regs->trap & 1);
1119 printf("stepped to ");
1120 xmon_print_symbol(regs->nip, " ", "\n");
1121 ppc_inst_dump(regs->nip, 1, 0);
1122 return 0;
1123 }
1124 }
1125 }
1126 regs->msr |= MSR_SE;
1127 return 1;
1128}
cdd3904d 1129#endif
1da177e4
LT
1130
1131static void bootcmds(void)
1132{
1133 int cmd;
1134
1135 cmd = inchar();
1136 if (cmd == 'r')
1137 ppc_md.restart(NULL);
1138 else if (cmd == 'h')
1139 ppc_md.halt();
1140 else if (cmd == 'p')
9178ba29
AG
1141 if (pm_power_off)
1142 pm_power_off();
1da177e4
LT
1143}
1144
1145static int cpu_cmd(void)
1146{
1147#ifdef CONFIG_SMP
fd3bb912 1148 unsigned long cpu, first_cpu, last_cpu;
1da177e4 1149 int timeout;
1da177e4
LT
1150
1151 if (!scanhex(&cpu)) {
1152 /* print cpus waiting or in xmon */
1153 printf("cpus stopped:");
fd3bb912 1154 last_cpu = first_cpu = NR_CPUS;
bc1d7702 1155 for_each_possible_cpu(cpu) {
104699c0 1156 if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
fd3bb912
PM
1157 if (cpu == last_cpu + 1) {
1158 last_cpu = cpu;
1159 } else {
1160 if (last_cpu != first_cpu)
736256e4 1161 printf("-0x%lx", last_cpu);
fd3bb912 1162 last_cpu = first_cpu = cpu;
736256e4 1163 printf(" 0x%lx", cpu);
fd3bb912 1164 }
1da177e4
LT
1165 }
1166 }
fd3bb912 1167 if (last_cpu != first_cpu)
736256e4 1168 printf("-0x%lx", last_cpu);
1da177e4
LT
1169 printf("\n");
1170 return 0;
1171 }
1172 /* try to switch to cpu specified */
104699c0 1173 if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
e70d8f55 1174 printf("cpu 0x%lx isn't in xmon\n", cpu);
7b08729c
ME
1175#ifdef CONFIG_PPC64
1176 printf("backtrace of paca[0x%lx].saved_r1 (possibly stale):\n", cpu);
1177 xmon_show_stack(paca_ptrs[cpu]->saved_r1, 0, 0);
1178#endif
1da177e4
LT
1179 return 0;
1180 }
1181 xmon_taken = 0;
1182 mb();
1183 xmon_owner = cpu;
1184 timeout = 10000000;
1185 while (!xmon_taken) {
1186 if (--timeout == 0) {
1187 if (test_and_set_bit(0, &xmon_taken))
1188 break;
1189 /* take control back */
1190 mb();
1191 xmon_owner = smp_processor_id();
e70d8f55 1192 printf("cpu 0x%lx didn't take control\n", cpu);
1da177e4
LT
1193 return 0;
1194 }
1195 barrier();
1196 }
1197 return 1;
1198#else
1199 return 0;
1200#endif /* CONFIG_SMP */
1201}
1202
1203static unsigned short fcstab[256] = {
1204 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
1205 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
1206 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
1207 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
1208 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
1209 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
1210 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
1211 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
1212 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
1213 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
1214 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
1215 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
1216 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
1217 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
1218 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
1219 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
1220 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
1221 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
1222 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
1223 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
1224 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
1225 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
1226 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
1227 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
1228 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
1229 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
1230 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
1231 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
1232 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
1233 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
1234 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
1235 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
1236};
1237
1238#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
1239
1240static void
1241csum(void)
1242{
1243 unsigned int i;
1244 unsigned short fcs;
1245 unsigned char v;
1246
1247 if (!scanhex(&adrs))
1248 return;
1249 if (!scanhex(&ncsum))
1250 return;
1251 fcs = 0xffff;
1252 for (i = 0; i < ncsum; ++i) {
1253 if (mread(adrs+i, &v, 1) == 0) {
736256e4 1254 printf("csum stopped at "REG"\n", adrs+i);
1da177e4
LT
1255 break;
1256 }
1257 fcs = FCS(fcs, v);
1258 }
1259 printf("%x\n", fcs);
1260}
1261
1262/*
1263 * Check if this is a suitable place to put a breakpoint.
1264 */
1265static long check_bp_loc(unsigned long addr)
1266{
1267 unsigned int instr;
1268
1269 addr &= ~3;
51fae6de 1270 if (!is_kernel_addr(addr)) {
1da177e4
LT
1271 printf("Breakpoints may only be placed at kernel addresses\n");
1272 return 0;
1273 }
1274 if (!mread(addr, &instr, sizeof(instr))) {
1275 printf("Can't read instruction at address %lx\n", addr);
1276 return 0;
1277 }
1278 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1279 printf("Breakpoints may not be placed on mtmsrd or rfid "
1280 "instructions\n");
1281 return 0;
1282 }
1283 return 1;
1284}
1285
e3bc8049 1286static char *breakpoint_help_string =
1da177e4
LT
1287 "Breakpoint command usage:\n"
1288 "b show breakpoints\n"
1289 "b <addr> [cnt] set breakpoint at given instr addr\n"
1290 "bc clear all breakpoints\n"
1291 "bc <n/addr> clear breakpoint number n or at addr\n"
1ad7d705 1292 "bi <addr> [cnt] set hardware instr breakpoint (POWER8 only)\n"
1da177e4
LT
1293 "bd <addr> [cnt] set hardware data breakpoint\n"
1294 "";
1295
1296static void
1297bpt_cmds(void)
1298{
1299 int cmd;
1300 unsigned long a;
09b6c112 1301 int i;
1da177e4 1302 struct bpt *bp;
1da177e4
LT
1303
1304 cmd = inchar();
1305 switch (cmd) {
09b6c112
NP
1306#ifndef CONFIG_PPC_8xx
1307 static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
1308 int mode;
1da177e4 1309 case 'd': /* bd - hardware data breakpoint */
9bc2bd5d
MN
1310 if (!ppc_breakpoint_available()) {
1311 printf("Hardware data breakpoint not supported on this cpu\n");
1312 break;
1313 }
1da177e4
LT
1314 mode = 7;
1315 cmd = inchar();
1316 if (cmd == 'r')
1317 mode = 5;
1318 else if (cmd == 'w')
1319 mode = 6;
1320 else
1321 termch = cmd;
1322 dabr.address = 0;
1323 dabr.enabled = 0;
1324 if (scanhex(&dabr.address)) {
51fae6de 1325 if (!is_kernel_addr(dabr.address)) {
1da177e4
LT
1326 printf(badaddr);
1327 break;
1328 }
9422de3e 1329 dabr.address &= ~HW_BRK_TYPE_DABR;
1da177e4
LT
1330 dabr.enabled = mode | BP_DABR;
1331 }
e1368d0c
VJ
1332
1333 force_enable_xmon();
1da177e4
LT
1334 break;
1335
1336 case 'i': /* bi - hardware instr breakpoint */
1ad7d705 1337 if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
1da177e4
LT
1338 printf("Hardware instruction breakpoint "
1339 "not supported on this cpu\n");
1340 break;
1341 }
1342 if (iabr) {
abb90ee7 1343 iabr->enabled &= ~BP_CIABR;
1da177e4
LT
1344 iabr = NULL;
1345 }
1346 if (!scanhex(&a))
1347 break;
1348 if (!check_bp_loc(a))
1349 break;
1350 bp = new_breakpoint(a);
1351 if (bp != NULL) {
abb90ee7 1352 bp->enabled |= BP_CIABR;
1da177e4 1353 iabr = bp;
e1368d0c 1354 force_enable_xmon();
1da177e4
LT
1355 }
1356 break;
f78541dc 1357#endif
1da177e4
LT
1358
1359 case 'c':
1360 if (!scanhex(&a)) {
1361 /* clear all breakpoints */
1362 for (i = 0; i < NBPTS; ++i)
1363 bpts[i].enabled = 0;
1364 iabr = NULL;
1365 dabr.enabled = 0;
1366 printf("All breakpoints cleared\n");
1367 break;
1368 }
1369
1370 if (a <= NBPTS && a >= 1) {
1371 /* assume a breakpoint number */
1372 bp = &bpts[a-1]; /* bp nums are 1 based */
1373 } else {
1374 /* assume a breakpoint address */
1375 bp = at_breakpoint(a);
9f1067c2 1376 if (bp == NULL) {
736256e4 1377 printf("No breakpoint at %lx\n", a);
1da177e4
LT
1378 break;
1379 }
1380 }
1381
e70d8f55 1382 printf("Cleared breakpoint %tx (", BP_NUM(bp));
1da177e4
LT
1383 xmon_print_symbol(bp->address, " ", ")\n");
1384 bp->enabled = 0;
1385 break;
1386
1387 default:
1388 termch = cmd;
e3bc8049 1389 cmd = skipbl();
1da177e4
LT
1390 if (cmd == '?') {
1391 printf(breakpoint_help_string);
1392 break;
1393 }
1394 termch = cmd;
1395 if (!scanhex(&a)) {
1396 /* print all breakpoints */
1397 printf(" type address\n");
1398 if (dabr.enabled) {
f78541dc 1399 printf(" data "REG" [", dabr.address);
1da177e4
LT
1400 if (dabr.enabled & 1)
1401 printf("r");
1402 if (dabr.enabled & 2)
1403 printf("w");
1404 printf("]\n");
1405 }
1406 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1407 if (!bp->enabled)
1408 continue;
e70d8f55 1409 printf("%tx %s ", BP_NUM(bp),
abb90ee7 1410 (bp->enabled & BP_CIABR) ? "inst": "trap");
1da177e4
LT
1411 xmon_print_symbol(bp->address, " ", "\n");
1412 }
1413 break;
1414 }
1415
1416 if (!check_bp_loc(a))
1417 break;
1418 bp = new_breakpoint(a);
e1368d0c 1419 if (bp != NULL) {
1da177e4 1420 bp->enabled |= BP_TRAP;
e1368d0c
VJ
1421 force_enable_xmon();
1422 }
1da177e4
LT
1423 break;
1424 }
1425}
1426
1427/* Very cheap human name for vector lookup. */
1428static
1429const char *getvecname(unsigned long vec)
1430{
1431 char *ret;
1432
1433 switch (vec) {
1434 case 0x100: ret = "(System Reset)"; break;
1435 case 0x200: ret = "(Machine Check)"; break;
1436 case 0x300: ret = "(Data Access)"; break;
8915bcd6
MN
1437 case 0x380:
1438 if (radix_enabled())
1439 ret = "(Data Access Out of Range)";
1440 else
1441 ret = "(Data SLB Access)";
1442 break;
1da177e4 1443 case 0x400: ret = "(Instruction Access)"; break;
8915bcd6
MN
1444 case 0x480:
1445 if (radix_enabled())
1446 ret = "(Instruction Access Out of Range)";
1447 else
1448 ret = "(Instruction SLB Access)";
1449 break;
1da177e4
LT
1450 case 0x500: ret = "(Hardware Interrupt)"; break;
1451 case 0x600: ret = "(Alignment)"; break;
1452 case 0x700: ret = "(Program Check)"; break;
1453 case 0x800: ret = "(FPU Unavailable)"; break;
1454 case 0x900: ret = "(Decrementer)"; break;
660e034c
ME
1455 case 0x980: ret = "(Hypervisor Decrementer)"; break;
1456 case 0xa00: ret = "(Doorbell)"; break;
1da177e4
LT
1457 case 0xc00: ret = "(System Call)"; break;
1458 case 0xd00: ret = "(Single Step)"; break;
660e034c
ME
1459 case 0xe40: ret = "(Emulation Assist)"; break;
1460 case 0xe60: ret = "(HMI)"; break;
1461 case 0xe80: ret = "(Hypervisor Doorbell)"; break;
1da177e4
LT
1462 case 0xf00: ret = "(Performance Monitor)"; break;
1463 case 0xf20: ret = "(Altivec Unavailable)"; break;
1464 case 0x1300: ret = "(Instruction Breakpoint)"; break;
660e034c
ME
1465 case 0x1500: ret = "(Denormalisation)"; break;
1466 case 0x1700: ret = "(Altivec Assist)"; break;
1da177e4
LT
1467 default: ret = "";
1468 }
1469 return ret;
1470}
1471
1472static void get_function_bounds(unsigned long pc, unsigned long *startp,
1473 unsigned long *endp)
1474{
1475 unsigned long size, offset;
1476 const char *name;
1da177e4
LT
1477
1478 *startp = *endp = 0;
1479 if (pc == 0)
1480 return;
1481 if (setjmp(bus_error_jmp) == 0) {
1482 catch_memory_errors = 1;
1483 sync();
ffb45122 1484 name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
1da177e4
LT
1485 if (name != NULL) {
1486 *startp = pc - offset;
1487 *endp = pc - offset + size;
1488 }
1489 sync();
1490 }
1491 catch_memory_errors = 0;
1492}
1493
ec2b36b9
BH
1494#define LRSAVE_OFFSET (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1495#define MARKER_OFFSET (STACK_FRAME_MARKER * sizeof(unsigned long))
1496
1da177e4
LT
1497static void xmon_show_stack(unsigned long sp, unsigned long lr,
1498 unsigned long pc)
1499{
0104cd68 1500 int max_to_print = 64;
1da177e4
LT
1501 unsigned long ip;
1502 unsigned long newsp;
1503 unsigned long marker;
1da177e4
LT
1504 struct pt_regs regs;
1505
0104cd68 1506 while (max_to_print--) {
e71ff89c 1507 if (!is_kernel_addr(sp)) {
1da177e4
LT
1508 if (sp != 0)
1509 printf("SP (%lx) is in userspace\n", sp);
1510 break;
1511 }
1512
f78541dc 1513 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1da177e4
LT
1514 || !mread(sp, &newsp, sizeof(unsigned long))) {
1515 printf("Couldn't read stack frame at %lx\n", sp);
1516 break;
1517 }
1518
1519 /*
1520 * For the first stack frame, try to work out if
1521 * LR and/or the saved LR value in the bottommost
1522 * stack frame are valid.
1523 */
1524 if ((pc | lr) != 0) {
1525 unsigned long fnstart, fnend;
1526 unsigned long nextip;
1527 int printip = 1;
1528
1529 get_function_bounds(pc, &fnstart, &fnend);
1530 nextip = 0;
1531 if (newsp > sp)
f78541dc 1532 mread(newsp + LRSAVE_OFFSET, &nextip,
1da177e4
LT
1533 sizeof(unsigned long));
1534 if (lr == ip) {
e71ff89c 1535 if (!is_kernel_addr(lr)
1da177e4
LT
1536 || (fnstart <= lr && lr < fnend))
1537 printip = 0;
1538 } else if (lr == nextip) {
1539 printip = 0;
e71ff89c 1540 } else if (is_kernel_addr(lr)
1da177e4
LT
1541 && !(fnstart <= lr && lr < fnend)) {
1542 printf("[link register ] ");
1543 xmon_print_symbol(lr, " ", "\n");
1544 }
1545 if (printip) {
f78541dc 1546 printf("["REG"] ", sp);
1da177e4
LT
1547 xmon_print_symbol(ip, " ", " (unreliable)\n");
1548 }
1549 pc = lr = 0;
1550
1551 } else {
f78541dc 1552 printf("["REG"] ", sp);
1da177e4
LT
1553 xmon_print_symbol(ip, " ", "\n");
1554 }
1555
1556 /* Look for "regshere" marker to see if this is
1557 an exception frame. */
f78541dc 1558 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
ec2b36b9 1559 && marker == STACK_FRAME_REGS_MARKER) {
c4de3809 1560 if (mread(sp + STACK_FRAME_OVERHEAD, &regs, sizeof(regs))
1da177e4
LT
1561 != sizeof(regs)) {
1562 printf("Couldn't read registers at %lx\n",
c4de3809 1563 sp + STACK_FRAME_OVERHEAD);
1da177e4
LT
1564 break;
1565 }
e3bc8049 1566 printf("--- Exception: %lx %s at ", regs.trap,
1da177e4
LT
1567 getvecname(TRAP(&regs)));
1568 pc = regs.nip;
1569 lr = regs.link;
1570 xmon_print_symbol(pc, " ", "\n");
1571 }
1572
1573 if (newsp == 0)
1574 break;
1575
1576 sp = newsp;
0104cd68 1577 }
1da177e4
LT
1578}
1579
1580static void backtrace(struct pt_regs *excp)
1581{
1582 unsigned long sp;
1583
1584 if (scanhex(&sp))
1585 xmon_show_stack(sp, 0, 0);
1586 else
1587 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1588 scannl();
1589}
1590
1591static void print_bug_trap(struct pt_regs *regs)
1592{
ebdba9af 1593#ifdef CONFIG_BUG
73c9ceab 1594 const struct bug_entry *bug;
1da177e4
LT
1595 unsigned long addr;
1596
1597 if (regs->msr & MSR_PR)
1598 return; /* not in kernel */
1599 addr = regs->nip; /* address of trap instruction */
e71ff89c 1600 if (!is_kernel_addr(addr))
1da177e4
LT
1601 return;
1602 bug = find_bug(regs->nip);
1603 if (bug == NULL)
1604 return;
73c9ceab 1605 if (is_warning_bug(bug))
1da177e4
LT
1606 return;
1607
0a7c7efc 1608#ifdef CONFIG_DEBUG_BUGVERBOSE
73c9ceab
JF
1609 printf("kernel BUG at %s:%u!\n",
1610 bug->file, bug->line);
0a7c7efc 1611#else
d8104182 1612 printf("kernel BUG at %px!\n", (void *)bug->bug_addr);
0a7c7efc 1613#endif
ebdba9af 1614#endif /* CONFIG_BUG */
1da177e4
LT
1615}
1616
9f1067c2 1617static void excprint(struct pt_regs *fp)
1da177e4
LT
1618{
1619 unsigned long trap;
1620
1621#ifdef CONFIG_SMP
1622 printf("cpu 0x%x: ", smp_processor_id());
1623#endif /* CONFIG_SMP */
1624
1625 trap = TRAP(fp);
e70d8f55 1626 printf("Vector: %lx %s at [%px]\n", fp->trap, getvecname(trap), fp);
1da177e4
LT
1627 printf(" pc: ");
1628 xmon_print_symbol(fp->nip, ": ", "\n");
1629
e70d8f55 1630 printf(" lr: ");
1da177e4
LT
1631 xmon_print_symbol(fp->link, ": ", "\n");
1632
1633 printf(" sp: %lx\n", fp->gpr[1]);
1634 printf(" msr: %lx\n", fp->msr);
1635
ce54152f 1636 if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
1da177e4
LT
1637 printf(" dar: %lx\n", fp->dar);
1638 if (trap != 0x380)
1639 printf(" dsisr: %lx\n", fp->dsisr);
1640 }
1641
e70d8f55 1642 printf(" current = 0x%px\n", current);
f78541dc 1643#ifdef CONFIG_PPC64
3130a7bb 1644 printf(" paca = 0x%px\t irqmask: 0x%02x\t irq_happened: 0x%02x\n",
4e26bc4a 1645 local_paca, local_paca->irq_soft_mask, local_paca->irq_happened);
f78541dc 1646#endif
1da177e4 1647 if (current) {
e70d8f55 1648 printf(" pid = %d, comm = %s\n",
1da177e4
LT
1649 current->pid, current->comm);
1650 }
1651
1652 if (trap == 0x700)
1653 print_bug_trap(fp);
eb925d64
RG
1654
1655 printf(linux_banner);
1da177e4
LT
1656}
1657
9f1067c2 1658static void prregs(struct pt_regs *fp)
1da177e4 1659{
f78541dc 1660 int n, trap;
1da177e4
LT
1661 unsigned long base;
1662 struct pt_regs regs;
1663
1664 if (scanhex(&base)) {
1665 if (setjmp(bus_error_jmp) == 0) {
1666 catch_memory_errors = 1;
1667 sync();
1668 regs = *(struct pt_regs *)base;
1669 sync();
1670 __delay(200);
1671 } else {
1672 catch_memory_errors = 0;
f78541dc 1673 printf("*** Error reading registers from "REG"\n",
1da177e4
LT
1674 base);
1675 return;
1676 }
1677 catch_memory_errors = 0;
1678 fp = &regs;
1679 }
1680
f78541dc 1681#ifdef CONFIG_PPC64
1da177e4
LT
1682 if (FULL_REGS(fp)) {
1683 for (n = 0; n < 16; ++n)
e70d8f55 1684 printf("R%.2d = "REG" R%.2d = "REG"\n",
1da177e4
LT
1685 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1686 } else {
1687 for (n = 0; n < 7; ++n)
e70d8f55 1688 printf("R%.2d = "REG" R%.2d = "REG"\n",
1da177e4
LT
1689 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1690 }
f78541dc
PM
1691#else
1692 for (n = 0; n < 32; ++n) {
e70d8f55 1693 printf("R%.2d = %.8lx%s", n, fp->gpr[n],
f78541dc
PM
1694 (n & 3) == 3? "\n": " ");
1695 if (n == 12 && !FULL_REGS(fp)) {
1696 printf("\n");
1697 break;
1698 }
1699 }
1700#endif
1da177e4
LT
1701 printf("pc = ");
1702 xmon_print_symbol(fp->nip, " ", "\n");
48404f2e
PM
1703 if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
1704 printf("cfar= ");
1705 xmon_print_symbol(fp->orig_gpr3, " ", "\n");
1706 }
1da177e4
LT
1707 printf("lr = ");
1708 xmon_print_symbol(fp->link, " ", "\n");
f78541dc
PM
1709 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1710 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1da177e4 1711 fp->ctr, fp->xer, fp->trap);
f78541dc
PM
1712 trap = TRAP(fp);
1713 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1714 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1da177e4
LT
1715}
1716
9f1067c2 1717static void cacheflush(void)
1da177e4
LT
1718{
1719 int cmd;
1720 unsigned long nflush;
1721
1722 cmd = inchar();
1723 if (cmd != 'i')
1724 termch = cmd;
1725 scanhex((void *)&adrs);
1726 if (termch != '\n')
1727 termch = 0;
1728 nflush = 1;
1729 scanhex(&nflush);
1730 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1731 if (setjmp(bus_error_jmp) == 0) {
1732 catch_memory_errors = 1;
1733 sync();
1734
1735 if (cmd != 'i') {
1736 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1737 cflush((void *) adrs);
1738 } else {
1739 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1740 cinval((void *) adrs);
1741 }
1742 sync();
1743 /* wait a little while to see if we get a machine check */
1744 __delay(200);
1745 }
1746 catch_memory_errors = 0;
1747}
1748
31cdd0c3
PM
1749extern unsigned long xmon_mfspr(int spr, unsigned long default_value);
1750extern void xmon_mtspr(int spr, unsigned long value);
1751
1752static int
1753read_spr(int n, unsigned long *vp)
1da177e4 1754{
1da177e4 1755 unsigned long ret = -1UL;
31cdd0c3 1756 int ok = 0;
1da177e4
LT
1757
1758 if (setjmp(bus_error_jmp) == 0) {
31cdd0c3 1759 catch_spr_faults = 1;
1da177e4
LT
1760 sync();
1761
31cdd0c3 1762 ret = xmon_mfspr(n, *vp);
1da177e4
LT
1763
1764 sync();
31cdd0c3
PM
1765 *vp = ret;
1766 ok = 1;
1da177e4 1767 }
31cdd0c3 1768 catch_spr_faults = 0;
1da177e4 1769
31cdd0c3 1770 return ok;
1da177e4
LT
1771}
1772
9f1067c2 1773static void
1da177e4
LT
1774write_spr(int n, unsigned long val)
1775{
1da177e4 1776 if (setjmp(bus_error_jmp) == 0) {
31cdd0c3 1777 catch_spr_faults = 1;
1da177e4
LT
1778 sync();
1779
31cdd0c3 1780 xmon_mtspr(n, val);
1da177e4
LT
1781
1782 sync();
31cdd0c3
PM
1783 } else {
1784 printf("SPR 0x%03x (%4d) Faulted during write\n", n, n);
1da177e4 1785 }
31cdd0c3 1786 catch_spr_faults = 0;
1da177e4
LT
1787}
1788
1846193b
ME
1789static void dump_206_sprs(void)
1790{
1791#ifdef CONFIG_PPC64
1792 if (!cpu_has_feature(CPU_FTR_ARCH_206))
1793 return;
1794
1795 /* Actually some of these pre-date 2.06, but whatevs */
1796
e70d8f55 1797 printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8lx\n",
1846193b 1798 mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR));
e70d8f55 1799 printf("dscr = %.16lx ppr = %.16lx pir = %.8lx\n",
1846193b 1800 mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR));
64d66aa0
BS
1801 printf("amr = %.16lx uamor = %.16lx\n",
1802 mfspr(SPRN_AMR), mfspr(SPRN_UAMOR));
1846193b
ME
1803
1804 if (!(mfmsr() & MSR_HV))
1805 return;
1806
e70d8f55 1807 printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8lx\n",
1846193b 1808 mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR));
64d66aa0 1809 printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n",
1846193b 1810 mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC));
e70d8f55 1811 printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8lx\n",
1846193b 1812 mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID));
64d66aa0
BS
1813 printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n",
1814 mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR));
c47a9403 1815 printf("dabr = %.16lx dabrx = %.16lx\n",
1846193b
ME
1816 mfspr(SPRN_DABR), mfspr(SPRN_DABRX));
1817#endif
1818}
1819
e0ddf7a2
ME
1820static void dump_207_sprs(void)
1821{
1822#ifdef CONFIG_PPC64
1823 unsigned long msr;
1824
1825 if (!cpu_has_feature(CPU_FTR_ARCH_207S))
1826 return;
1827
e70d8f55 1828 printf("dpdes = %.16lx tir = %.16lx cir = %.8lx\n",
e0ddf7a2
ME
1829 mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR));
1830
e70d8f55 1831 printf("fscr = %.16lx tar = %.16lx pspb = %.8lx\n",
e0ddf7a2
ME
1832 mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB));
1833
1834 msr = mfmsr();
1835 if (msr & MSR_TM) {
1836 /* Only if TM has been enabled in the kernel */
c47a9403 1837 printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n",
e0ddf7a2
ME
1838 mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR),
1839 mfspr(SPRN_TEXASR));
1840 }
1841
c47a9403 1842 printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n",
e0ddf7a2 1843 mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2));
e70d8f55 1844 printf("pmc1 = %.8lx pmc2 = %.8lx pmc3 = %.8lx pmc4 = %.8lx\n",
e0ddf7a2
ME
1845 mfspr(SPRN_PMC1), mfspr(SPRN_PMC2),
1846 mfspr(SPRN_PMC3), mfspr(SPRN_PMC4));
e70d8f55 1847 printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8lx\n",
e0ddf7a2 1848 mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5));
e70d8f55 1849 printf("sdar = %.16lx sier = %.16lx pmc6 = %.8lx\n",
e0ddf7a2 1850 mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6));
c47a9403 1851 printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n",
e0ddf7a2 1852 mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
64d66aa0 1853 printf("iamr = %.16lx\n", mfspr(SPRN_IAMR));
e0ddf7a2
ME
1854
1855 if (!(msr & MSR_HV))
1856 return;
1857
c47a9403 1858 printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
e0ddf7a2 1859 mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
c47a9403 1860 printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n",
e0ddf7a2
ME
1861 mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR));
1862#endif
1863}
1da177e4 1864
d1e1b351
BS
1865static void dump_300_sprs(void)
1866{
1867#ifdef CONFIG_PPC64
1868 bool hv = mfmsr() & MSR_HV;
1869
1870 if (!cpu_has_feature(CPU_FTR_ARCH_300))
1871 return;
1872
1873 printf("pidr = %.16lx tidr = %.16lx\n",
1874 mfspr(SPRN_PID), mfspr(SPRN_TIDR));
1875 printf("asdr = %.16lx psscr = %.16lx\n",
1876 mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR)
1877 : mfspr(SPRN_PSSCR_PR));
1878
1879 if (!hv)
1880 return;
1881
1882 printf("ptcr = %.16lx\n",
1883 mfspr(SPRN_PTCR));
1884#endif
1885}
1886
31cdd0c3
PM
1887static void dump_one_spr(int spr, bool show_unimplemented)
1888{
1889 unsigned long val;
1890
1891 val = 0xdeadbeef;
1892 if (!read_spr(spr, &val)) {
1893 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1894 return;
1895 }
1896
1897 if (val == 0xdeadbeef) {
1898 /* Looks like read was a nop, confirm */
1899 val = 0x0badcafe;
1900 if (!read_spr(spr, &val)) {
1901 printf("SPR 0x%03x (%4d) Faulted during read\n", spr, spr);
1902 return;
1903 }
1904
1905 if (val == 0x0badcafe) {
1906 if (show_unimplemented)
1907 printf("SPR 0x%03x (%4d) Unimplemented\n", spr, spr);
1908 return;
1909 }
1910 }
1911
1912 printf("SPR 0x%03x (%4d) = 0x%lx\n", spr, spr, val);
1913}
1914
9f1067c2 1915static void super_regs(void)
1da177e4 1916{
13629dad 1917 static unsigned long regno;
1da177e4 1918 int cmd;
31cdd0c3 1919 int spr;
1da177e4
LT
1920
1921 cmd = skipbl();
31cdd0c3
PM
1922
1923 switch (cmd) {
1924 case '\n': {
e3bc8049 1925 unsigned long sp, toc;
1da177e4
LT
1926 asm("mr %0,1" : "=r" (sp) :);
1927 asm("mr %0,2" : "=r" (toc) :);
1928
56346ad8 1929 printf("msr = "REG" sprg0 = "REG"\n",
f78541dc 1930 mfmsr(), mfspr(SPRN_SPRG0));
56346ad8 1931 printf("pvr = "REG" sprg1 = "REG"\n",
e3bc8049 1932 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
56346ad8 1933 printf("dec = "REG" sprg2 = "REG"\n",
f78541dc 1934 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
56346ad8
ME
1935 printf("sp = "REG" sprg3 = "REG"\n", sp, mfspr(SPRN_SPRG3));
1936 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1937
1846193b 1938 dump_206_sprs();
e0ddf7a2 1939 dump_207_sprs();
d1e1b351 1940 dump_300_sprs();
1846193b 1941
1da177e4
LT
1942 return;
1943 }
31cdd0c3
PM
1944 case 'w': {
1945 unsigned long val;
1946 scanhex(&regno);
1947 val = 0;
1948 read_spr(regno, &val);
1da177e4
LT
1949 scanhex(&val);
1950 write_spr(regno, val);
31cdd0c3
PM
1951 dump_one_spr(regno, true);
1952 break;
1953 }
1da177e4 1954 case 'r':
31cdd0c3
PM
1955 scanhex(&regno);
1956 dump_one_spr(regno, true);
1957 break;
1958 case 'a':
1959 /* dump ALL SPRs */
1960 for (spr = 1; spr < 1024; ++spr)
1961 dump_one_spr(spr, false);
1da177e4 1962 break;
1da177e4 1963 }
31cdd0c3 1964
1da177e4
LT
1965 scannl();
1966}
1967
1968/*
1969 * Stuff for reading and writing memory safely
1970 */
9f1067c2 1971static int
1da177e4
LT
1972mread(unsigned long adrs, void *buf, int size)
1973{
1974 volatile int n;
1975 char *p, *q;
1976
1977 n = 0;
1978 if (setjmp(bus_error_jmp) == 0) {
1979 catch_memory_errors = 1;
1980 sync();
1981 p = (char *)adrs;
1982 q = (char *)buf;
1983 switch (size) {
1984 case 2:
f78541dc 1985 *(u16 *)q = *(u16 *)p;
1da177e4
LT
1986 break;
1987 case 4:
f78541dc 1988 *(u32 *)q = *(u32 *)p;
1da177e4
LT
1989 break;
1990 case 8:
f78541dc 1991 *(u64 *)q = *(u64 *)p;
1da177e4
LT
1992 break;
1993 default:
1994 for( ; n < size; ++n) {
1995 *q++ = *p++;
1996 sync();
1997 }
1998 }
1999 sync();
2000 /* wait a little while to see if we get a machine check */
2001 __delay(200);
2002 n = size;
2003 }
2004 catch_memory_errors = 0;
2005 return n;
2006}
2007
9f1067c2 2008static int
1da177e4
LT
2009mwrite(unsigned long adrs, void *buf, int size)
2010{
2011 volatile int n;
2012 char *p, *q;
2013
2014 n = 0;
2015 if (setjmp(bus_error_jmp) == 0) {
2016 catch_memory_errors = 1;
2017 sync();
2018 p = (char *) adrs;
2019 q = (char *) buf;
2020 switch (size) {
2021 case 2:
f78541dc 2022 *(u16 *)p = *(u16 *)q;
1da177e4
LT
2023 break;
2024 case 4:
f78541dc 2025 *(u32 *)p = *(u32 *)q;
1da177e4
LT
2026 break;
2027 case 8:
f78541dc 2028 *(u64 *)p = *(u64 *)q;
1da177e4
LT
2029 break;
2030 default:
2031 for ( ; n < size; ++n) {
2032 *p++ = *q++;
2033 sync();
2034 }
2035 }
2036 sync();
2037 /* wait a little while to see if we get a machine check */
2038 __delay(200);
2039 n = size;
2040 } else {
736256e4 2041 printf("*** Error writing address "REG"\n", adrs + n);
1da177e4
LT
2042 }
2043 catch_memory_errors = 0;
2044 return n;
2045}
2046
2047static int fault_type;
f78541dc 2048static int fault_except;
1da177e4
LT
2049static char *fault_chars[] = { "--", "**", "##" };
2050
f78541dc 2051static int handle_fault(struct pt_regs *regs)
1da177e4 2052{
f78541dc 2053 fault_except = TRAP(regs);
1da177e4
LT
2054 switch (TRAP(regs)) {
2055 case 0x200:
2056 fault_type = 0;
2057 break;
2058 case 0x300:
2059 case 0x380:
2060 fault_type = 1;
2061 break;
2062 default:
2063 fault_type = 2;
2064 }
2065
2066 longjmp(bus_error_jmp, 1);
2067
2068 return 0;
2069}
2070
2071#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
2072
9f1067c2 2073static void
1da177e4
LT
2074byterev(unsigned char *val, int size)
2075{
2076 int t;
2077
2078 switch (size) {
2079 case 2:
2080 SWAP(val[0], val[1], t);
2081 break;
2082 case 4:
2083 SWAP(val[0], val[3], t);
2084 SWAP(val[1], val[2], t);
2085 break;
2086 case 8: /* is there really any use for this? */
2087 SWAP(val[0], val[7], t);
2088 SWAP(val[1], val[6], t);
2089 SWAP(val[2], val[5], t);
2090 SWAP(val[3], val[4], t);
2091 break;
2092 }
2093}
2094
2095static int brev;
2096static int mnoread;
2097
e3bc8049 2098static char *memex_help_string =
1da177e4
LT
2099 "Memory examine command usage:\n"
2100 "m [addr] [flags] examine/change memory\n"
2101 " addr is optional. will start where left off.\n"
2102 " flags may include chars from this set:\n"
2103 " b modify by bytes (default)\n"
2104 " w modify by words (2 byte)\n"
2105 " l modify by longs (4 byte)\n"
2106 " d modify by doubleword (8 byte)\n"
2107 " r toggle reverse byte order mode\n"
2108 " n do not read memory (for i/o spaces)\n"
2109 " . ok to read (default)\n"
2110 "NOTE: flags are saved as defaults\n"
2111 "";
2112
e3bc8049 2113static char *memex_subcmd_help_string =
1da177e4
LT
2114 "Memory examine subcommands:\n"
2115 " hexval write this val to current location\n"
2116 " 'string' write chars from string to this location\n"
2117 " ' increment address\n"
2118 " ^ decrement address\n"
2119 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
2120 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
2121 " ` clear no-read flag\n"
2122 " ; stay at this addr\n"
2123 " v change to byte mode\n"
2124 " w change to word (2 byte) mode\n"
2125 " l change to long (4 byte) mode\n"
2126 " u change to doubleword (8 byte) mode\n"
2127 " m addr change current addr\n"
2128 " n toggle no-read flag\n"
2129 " r toggle byte reverse flag\n"
2130 " < count back up count bytes\n"
2131 " > count skip forward count bytes\n"
2132 " x exit this mode\n"
2133 "";
2134
9f1067c2 2135static void
1da177e4
LT
2136memex(void)
2137{
2138 int cmd, inc, i, nslash;
2139 unsigned long n;
2140 unsigned char val[16];
2141
2142 scanhex((void *)&adrs);
2143 cmd = skipbl();
2144 if (cmd == '?') {
2145 printf(memex_help_string);
2146 return;
2147 } else {
2148 termch = cmd;
2149 }
2150 last_cmd = "m\n";
2151 while ((cmd = skipbl()) != '\n') {
2152 switch( cmd ){
2153 case 'b': size = 1; break;
2154 case 'w': size = 2; break;
2155 case 'l': size = 4; break;
2156 case 'd': size = 8; break;
2157 case 'r': brev = !brev; break;
2158 case 'n': mnoread = 1; break;
2159 case '.': mnoread = 0; break;
2160 }
2161 }
2162 if( size <= 0 )
2163 size = 1;
2164 else if( size > 8 )
2165 size = 8;
2166 for(;;){
2167 if (!mnoread)
2168 n = mread(adrs, val, size);
e1449ed9 2169 printf(REG"%c", adrs, brev? 'r': ' ');
1da177e4
LT
2170 if (!mnoread) {
2171 if (brev)
2172 byterev(val, size);
2173 putchar(' ');
2174 for (i = 0; i < n; ++i)
2175 printf("%.2x", val[i]);
2176 for (; i < size; ++i)
2177 printf("%s", fault_chars[fault_type]);
2178 }
2179 putchar(' ');
2180 inc = size;
2181 nslash = 0;
2182 for(;;){
2183 if( scanhex(&n) ){
2184 for (i = 0; i < size; ++i)
2185 val[i] = n >> (i * 8);
2186 if (!brev)
2187 byterev(val, size);
2188 mwrite(adrs, val, size);
2189 inc = size;
2190 }
2191 cmd = skipbl();
2192 if (cmd == '\n')
2193 break;
2194 inc = 0;
2195 switch (cmd) {
2196 case '\'':
2197 for(;;){
2198 n = inchar();
2199 if( n == '\\' )
2200 n = bsesc();
2201 else if( n == '\'' )
2202 break;
2203 for (i = 0; i < size; ++i)
2204 val[i] = n >> (i * 8);
2205 if (!brev)
2206 byterev(val, size);
2207 mwrite(adrs, val, size);
2208 adrs += size;
2209 }
2210 adrs -= size;
2211 inc = size;
2212 break;
2213 case ',':
2214 adrs += size;
2215 break;
2216 case '.':
2217 mnoread = 0;
2218 break;
2219 case ';':
2220 break;
2221 case 'x':
2222 case EOF:
2223 scannl();
2224 return;
2225 case 'b':
2226 case 'v':
2227 size = 1;
2228 break;
2229 case 'w':
2230 size = 2;
2231 break;
2232 case 'l':
2233 size = 4;
2234 break;
2235 case 'u':
2236 size = 8;
2237 break;
2238 case '^':
2239 adrs -= size;
2240 break;
1da177e4
LT
2241 case '/':
2242 if (nslash > 0)
2243 adrs -= 1 << nslash;
2244 else
2245 nslash = 0;
2246 nslash += 4;
2247 adrs += 1 << nslash;
2248 break;
2249 case '\\':
2250 if (nslash < 0)
2251 adrs += 1 << -nslash;
2252 else
2253 nslash = 0;
2254 nslash -= 4;
2255 adrs -= 1 << -nslash;
2256 break;
2257 case 'm':
2258 scanhex((void *)&adrs);
2259 break;
2260 case 'n':
2261 mnoread = 1;
2262 break;
2263 case 'r':
2264 brev = !brev;
2265 break;
2266 case '<':
2267 n = size;
2268 scanhex(&n);
2269 adrs -= n;
2270 break;
2271 case '>':
2272 n = size;
2273 scanhex(&n);
2274 adrs += n;
2275 break;
2276 case '?':
2277 printf(memex_subcmd_help_string);
2278 break;
2279 }
2280 }
2281 adrs += inc;
2282 }
2283}
2284
9f1067c2 2285static int
1da177e4
LT
2286bsesc(void)
2287{
2288 int c;
2289
2290 c = inchar();
2291 switch( c ){
2292 case 'n': c = '\n'; break;
2293 case 'r': c = '\r'; break;
2294 case 'b': c = '\b'; break;
2295 case 't': c = '\t'; break;
2296 }
2297 return c;
2298}
2299
7e5b5938
OH
2300static void xmon_rawdump (unsigned long adrs, long ndump)
2301{
2302 long n, m, r, nr;
2303 unsigned char temp[16];
2304
2305 for (n = ndump; n > 0;) {
2306 r = n < 16? n: 16;
2307 nr = mread(adrs, temp, r);
2308 adrs += nr;
2309 for (m = 0; m < r; ++m) {
2310 if (m < nr)
2311 printf("%.2x", temp[m]);
2312 else
2313 printf("%s", fault_chars[fault_type]);
2314 }
2315 n -= r;
2316 if (nr < r)
2317 break;
2318 }
2319 printf("\n");
2320}
2321
4125d012
BL
2322static void dump_tracing(void)
2323{
2324 int c;
2325
2326 c = inchar();
2327 if (c == 'c')
2328 ftrace_dump(DUMP_ORIG);
2329 else
2330 ftrace_dump(DUMP_ALL);
4125d012
BL
2331}
2332
ddadb6b8
ME
2333#ifdef CONFIG_PPC64
2334static void dump_one_paca(int cpu)
2335{
2336 struct paca_struct *p;
4e003747 2337#ifdef CONFIG_PPC_BOOK3S_64
ad987fc8
ME
2338 int i = 0;
2339#endif
ddadb6b8
ME
2340
2341 if (setjmp(bus_error_jmp) != 0) {
2342 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2343 return;
2344 }
2345
2346 catch_memory_errors = 1;
2347 sync();
2348
d2e60075 2349 p = paca_ptrs[cpu];
ddadb6b8 2350
d8104182 2351 printf("paca for cpu 0x%x @ %px:\n", cpu, p);
ddadb6b8 2352
9ce53e27
ME
2353 printf(" %-*s = %s\n", 25, "possible", cpu_possible(cpu) ? "yes" : "no");
2354 printf(" %-*s = %s\n", 25, "present", cpu_present(cpu) ? "yes" : "no");
2355 printf(" %-*s = %s\n", 25, "online", cpu_online(cpu) ? "yes" : "no");
ddadb6b8 2356
6671683d 2357#define DUMP(paca, name, format) \
9ce53e27 2358 printf(" %-*s = "format"\t(0x%lx)\n", 25, #name, 18, paca->name, \
ddadb6b8
ME
2359 offsetof(struct paca_struct, name));
2360
6671683d
ME
2361 DUMP(p, lock_token, "%#-*x");
2362 DUMP(p, paca_index, "%#-*x");
e70d8f55
MM
2363 DUMP(p, kernel_toc, "%#-*llx");
2364 DUMP(p, kernelbase, "%#-*llx");
2365 DUMP(p, kernel_msr, "%#-*llx");
6671683d 2366 DUMP(p, emergency_sp, "%-*px");
729b0f71 2367#ifdef CONFIG_PPC_BOOK3S_64
6671683d
ME
2368 DUMP(p, nmi_emergency_sp, "%-*px");
2369 DUMP(p, mc_emergency_sp, "%-*px");
2370 DUMP(p, in_nmi, "%#-*x");
2371 DUMP(p, in_mce, "%#-*x");
2372 DUMP(p, hmi_event_available, "%#-*x");
729b0f71 2373#endif
e70d8f55 2374 DUMP(p, data_offset, "%#-*llx");
6671683d
ME
2375 DUMP(p, hw_cpu_id, "%#-*x");
2376 DUMP(p, cpu_start, "%#-*x");
2377 DUMP(p, kexec_state, "%#-*x");
4e003747 2378#ifdef CONFIG_PPC_BOOK3S_64
ad987fc8
ME
2379 for (i = 0; i < SLB_NUM_BOLTED; i++) {
2380 u64 esid, vsid;
2381
2382 if (!p->slb_shadow_ptr)
2383 continue;
2384
2385 esid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].esid);
2386 vsid = be64_to_cpu(p->slb_shadow_ptr->save_area[i].vsid);
2387
2388 if (esid || vsid) {
9ce53e27
ME
2389 printf(" %-*s[%d] = 0x%016llx 0x%016llx\n",
2390 22, "slb_shadow", i, esid, vsid);
ad987fc8
ME
2391 }
2392 }
6671683d
ME
2393 DUMP(p, vmalloc_sllp, "%#-*x");
2394 DUMP(p, slb_cache_ptr, "%#-*x");
ad987fc8 2395 for (i = 0; i < SLB_CACHE_ENTRIES; i++)
9ce53e27
ME
2396 printf(" %-*s[%d] = 0x%016x\n",
2397 22, "slb_cache", i, p->slb_cache[i]);
274920a3 2398
6671683d 2399 DUMP(p, rfi_flush_fallback_area, "%-*px");
ad987fc8 2400#endif
6671683d 2401 DUMP(p, dscr_default, "%#-*llx");
ad987fc8 2402#ifdef CONFIG_PPC_BOOK3E
6671683d
ME
2403 DUMP(p, pgd, "%-*px");
2404 DUMP(p, kernel_pgd, "%-*px");
2405 DUMP(p, tcd_ptr, "%-*px");
2406 DUMP(p, mc_kstack, "%-*px");
2407 DUMP(p, crit_kstack, "%-*px");
2408 DUMP(p, dbg_kstack, "%-*px");
ad987fc8 2409#endif
6671683d 2410 DUMP(p, __current, "%-*px");
e70d8f55 2411 DUMP(p, kstack, "%#-*llx");
9ce53e27 2412 printf(" %-*s = 0x%016llx\n", 25, "kstack_base", p->kstack & ~(THREAD_SIZE - 1));
e70d8f55
MM
2413 DUMP(p, stab_rr, "%#-*llx");
2414 DUMP(p, saved_r1, "%#-*llx");
6671683d
ME
2415 DUMP(p, trap_save, "%#-*x");
2416 DUMP(p, irq_soft_mask, "%#-*x");
2417 DUMP(p, irq_happened, "%#-*x");
2418 DUMP(p, io_sync, "%#-*x");
2419 DUMP(p, irq_work_pending, "%#-*x");
2420 DUMP(p, nap_state_lost, "%#-*x");
2421 DUMP(p, sprg_vdso, "%#-*llx");
ad987fc8
ME
2422
2423#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
6671683d 2424 DUMP(p, tm_scratch, "%#-*llx");
ad987fc8
ME
2425#endif
2426
2427#ifdef CONFIG_PPC_POWERNV
6671683d
ME
2428 DUMP(p, core_idle_state_ptr, "%-*px");
2429 DUMP(p, thread_idle_state, "%#-*x");
2430 DUMP(p, thread_mask, "%#-*x");
2431 DUMP(p, subcore_sibling_mask, "%#-*x");
2e0986d7
ME
2432 DUMP(p, thread_sibling_pacas, "%-*px");
2433 DUMP(p, requested_psscr, "%#-*llx");
2434 DUMP(p, stop_sprs.pid, "%#-*llx");
2435 DUMP(p, stop_sprs.ldbar, "%#-*llx");
2436 DUMP(p, stop_sprs.fscr, "%#-*llx");
2437 DUMP(p, stop_sprs.hfscr, "%#-*llx");
2438 DUMP(p, stop_sprs.mmcr1, "%#-*llx");
2439 DUMP(p, stop_sprs.mmcr2, "%#-*llx");
2440 DUMP(p, stop_sprs.mmcra, "%#-*llx");
2441 DUMP(p, dont_stop.counter, "%#-*x");
ad987fc8 2442#endif
ddadb6b8 2443
e70d8f55
MM
2444 DUMP(p, accounting.utime, "%#-*lx");
2445 DUMP(p, accounting.stime, "%#-*lx");
2446 DUMP(p, accounting.utime_scaled, "%#-*lx");
2447 DUMP(p, accounting.starttime, "%#-*lx");
2448 DUMP(p, accounting.starttime_user, "%#-*lx");
2449 DUMP(p, accounting.startspurr, "%#-*lx");
2450 DUMP(p, accounting.utime_sspurr, "%#-*lx");
2451 DUMP(p, accounting.steal_time, "%#-*lx");
ddadb6b8
ME
2452#undef DUMP
2453
2454 catch_memory_errors = 0;
2455 sync();
2456}
2457
2458static void dump_all_pacas(void)
2459{
2460 int cpu;
2461
2462 if (num_possible_cpus() == 0) {
2463 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2464 return;
2465 }
2466
2467 for_each_possible_cpu(cpu)
2468 dump_one_paca(cpu);
2469}
2470
2471static void dump_pacas(void)
2472{
2473 unsigned long num;
2474 int c;
2475
2476 c = inchar();
2477 if (c == 'a') {
2478 dump_all_pacas();
2479 return;
2480 }
2481
2482 termch = c; /* Put c back, it wasn't 'a' */
2483
2484 if (scanhex(&num))
2485 dump_one_paca(num);
2486 else
2487 dump_one_paca(xmon_owner);
2488}
2489#endif
2490
243e2511
BH
2491#ifdef CONFIG_PPC_POWERNV
2492static void dump_one_xive(int cpu)
2493{
2494 unsigned int hwid = get_hard_smp_processor_id(cpu);
2495
2496 opal_xive_dump(XIVE_DUMP_TM_HYP, hwid);
2497 opal_xive_dump(XIVE_DUMP_TM_POOL, hwid);
2498 opal_xive_dump(XIVE_DUMP_TM_OS, hwid);
2499 opal_xive_dump(XIVE_DUMP_TM_USER, hwid);
2500 opal_xive_dump(XIVE_DUMP_VP, hwid);
2501 opal_xive_dump(XIVE_DUMP_EMU_STATE, hwid);
2502
2503 if (setjmp(bus_error_jmp) != 0) {
2504 catch_memory_errors = 0;
2505 printf("*** Error dumping xive on cpu %d\n", cpu);
2506 return;
2507 }
2508
2509 catch_memory_errors = 1;
2510 sync();
2511 xmon_xive_do_dump(cpu);
2512 sync();
2513 __delay(200);
2514 catch_memory_errors = 0;
2515}
2516
2517static void dump_all_xives(void)
2518{
2519 int cpu;
2520
2521 if (num_possible_cpus() == 0) {
2522 printf("No possible cpus, use 'dx #' to dump individual cpus\n");
2523 return;
2524 }
2525
2526 for_each_possible_cpu(cpu)
2527 dump_one_xive(cpu);
2528}
2529
2530static void dump_one_xive_irq(u32 num)
2531{
2532 s64 rc;
2533 __be64 vp;
2534 u8 prio;
2535 __be32 lirq;
2536
2537 rc = opal_xive_get_irq_config(num, &vp, &prio, &lirq);
2538 xmon_printf("IRQ 0x%x config: vp=0x%llx prio=%d lirq=0x%x (rc=%lld)\n",
2539 num, be64_to_cpu(vp), prio, be32_to_cpu(lirq), rc);
2540}
2541
2542static void dump_xives(void)
2543{
2544 unsigned long num;
2545 int c;
2546
402e172a
BL
2547 if (!xive_enabled()) {
2548 printf("Xive disabled on this system\n");
2549 return;
2550 }
2551
243e2511
BH
2552 c = inchar();
2553 if (c == 'a') {
2554 dump_all_xives();
2555 return;
2556 } else if (c == 'i') {
2557 if (scanhex(&num))
2558 dump_one_xive_irq(num);
2559 return;
2560 }
2561
2562 termch = c; /* Put c back, it wasn't 'a' */
2563
2564 if (scanhex(&num))
2565 dump_one_xive(num);
2566 else
2567 dump_one_xive(xmon_owner);
2568}
2569#endif /* CONFIG_PPC_POWERNV */
2570
5e48dc0a
DM
2571static void dump_by_size(unsigned long addr, long count, int size)
2572{
2573 unsigned char temp[16];
2574 int i, j;
2575 u64 val;
2576
2577 count = ALIGN(count, 16);
2578
2579 for (i = 0; i < count; i += 16, addr += 16) {
2580 printf(REG, addr);
2581
2582 if (mread(addr, temp, 16) != 16) {
2583 printf("\nFaulted reading %d bytes from 0x"REG"\n", 16, addr);
2584 return;
2585 }
2586
2587 for (j = 0; j < 16; j += size) {
2588 putchar(' ');
2589 switch (size) {
2590 case 1: val = temp[j]; break;
2591 case 2: val = *(u16 *)&temp[j]; break;
2592 case 4: val = *(u32 *)&temp[j]; break;
2593 case 8: val = *(u64 *)&temp[j]; break;
2594 default: val = 0;
2595 }
2596
e70d8f55 2597 printf("%0*llx", size * 2, val);
5e48dc0a
DM
2598 }
2599 printf("\n");
2600 }
2601}
2602
9f1067c2 2603static void
1da177e4
LT
2604dump(void)
2605{
5e48dc0a 2606 static char last[] = { "d?\n" };
1da177e4
LT
2607 int c;
2608
2609 c = inchar();
ddadb6b8
ME
2610
2611#ifdef CONFIG_PPC64
2612 if (c == 'p') {
958b7c80 2613 xmon_start_pagination();
ddadb6b8 2614 dump_pacas();
958b7c80 2615 xmon_end_pagination();
ddadb6b8
ME
2616 return;
2617 }
2618#endif
243e2511
BH
2619#ifdef CONFIG_PPC_POWERNV
2620 if (c == 'x') {
2621 xmon_start_pagination();
2622 dump_xives();
2623 xmon_end_pagination();
2624 return;
2625 }
2626#endif
ddadb6b8 2627
4125d012
BL
2628 if (c == 't') {
2629 dump_tracing();
2630 return;
2631 }
2632
5e48dc0a 2633 if (c == '\n')
1da177e4 2634 termch = c;
5e48dc0a 2635
1da177e4
LT
2636 scanhex((void *)&adrs);
2637 if (termch != '\n')
2638 termch = 0;
2639 if (c == 'i') {
2640 scanhex(&nidump);
2641 if (nidump == 0)
2642 nidump = 16;
2643 else if (nidump > MAX_DUMP)
2644 nidump = MAX_DUMP;
2645 adrs += ppc_inst_dump(adrs, nidump, 1);
2646 last_cmd = "di\n";
f312deb4
VS
2647 } else if (c == 'l') {
2648 dump_log_buf();
fde93a0f
AD
2649 } else if (c == 'o') {
2650 dump_opal_msglog();
80eff6c4
BS
2651 } else if (c == 'v') {
2652 /* dump virtual to physical translation */
2653 show_pte(adrs);
7e5b5938
OH
2654 } else if (c == 'r') {
2655 scanhex(&ndump);
2656 if (ndump == 0)
2657 ndump = 64;
2658 xmon_rawdump(adrs, ndump);
2659 adrs += ndump;
2660 last_cmd = "dr\n";
1da177e4
LT
2661 } else {
2662 scanhex(&ndump);
2663 if (ndump == 0)
2664 ndump = 64;
2665 else if (ndump > MAX_DUMP)
2666 ndump = MAX_DUMP;
5e48dc0a
DM
2667
2668 switch (c) {
2669 case '8':
2670 case '4':
2671 case '2':
2672 case '1':
2673 ndump = ALIGN(ndump, 16);
2674 dump_by_size(adrs, ndump, c - '0');
2675 last[1] = c;
2676 last_cmd = last;
2677 break;
2678 default:
2679 prdump(adrs, ndump);
2680 last_cmd = "d\n";
2681 }
2682
1da177e4 2683 adrs += ndump;
1da177e4
LT
2684 }
2685}
2686
9f1067c2 2687static void
1da177e4
LT
2688prdump(unsigned long adrs, long ndump)
2689{
2690 long n, m, c, r, nr;
2691 unsigned char temp[16];
2692
2693 for (n = ndump; n > 0;) {
f78541dc 2694 printf(REG, adrs);
1da177e4
LT
2695 putchar(' ');
2696 r = n < 16? n: 16;
2697 nr = mread(adrs, temp, r);
2698 adrs += nr;
2699 for (m = 0; m < r; ++m) {
e3bc8049 2700 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
e1449ed9 2701 putchar(' ');
1da177e4
LT
2702 if (m < nr)
2703 printf("%.2x", temp[m]);
2704 else
2705 printf("%s", fault_chars[fault_type]);
2706 }
e1449ed9 2707 for (; m < 16; ++m) {
e3bc8049 2708 if ((m & (sizeof(long) - 1)) == 0)
e1449ed9 2709 putchar(' ');
1da177e4 2710 printf(" ");
e1449ed9 2711 }
1da177e4
LT
2712 printf(" |");
2713 for (m = 0; m < r; ++m) {
2714 if (m < nr) {
2715 c = temp[m];
2716 putchar(' ' <= c && c <= '~'? c: '.');
2717 } else
2718 putchar(' ');
2719 }
2720 n -= r;
2721 for (; m < 16; ++m)
2722 putchar(' ');
2723 printf("|\n");
2724 if (nr < r)
2725 break;
2726 }
2727}
2728
4c4c8723
ME
2729typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2730
9f1067c2 2731static int
4c4c8723
ME
2732generic_inst_dump(unsigned long adr, long count, int praddr,
2733 instruction_dump_func dump_func)
1da177e4
LT
2734{
2735 int nr, dotted;
2736 unsigned long first_adr;
2737 unsigned long inst, last_inst = 0;
2738 unsigned char val[4];
2739
2740 dotted = 0;
2741 for (first_adr = adr; count > 0; --count, adr += 4) {
2742 nr = mread(adr, val, 4);
2743 if (nr == 0) {
2744 if (praddr) {
2745 const char *x = fault_chars[fault_type];
f78541dc 2746 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
1da177e4
LT
2747 }
2748 break;
2749 }
2750 inst = GETWORD(val);
2751 if (adr > first_adr && inst == last_inst) {
2752 if (!dotted) {
2753 printf(" ...\n");
2754 dotted = 1;
2755 }
2756 continue;
2757 }
2758 dotted = 0;
2759 last_inst = inst;
2760 if (praddr)
e70d8f55 2761 printf(REG" %.8lx", adr, inst);
1da177e4 2762 printf("\t");
4c4c8723 2763 dump_func(inst, adr);
1da177e4
LT
2764 printf("\n");
2765 }
2766 return adr - first_adr;
2767}
2768
9f1067c2 2769static int
4c4c8723
ME
2770ppc_inst_dump(unsigned long adr, long count, int praddr)
2771{
2772 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2773}
2774
1da177e4
LT
2775void
2776print_address(unsigned long addr)
2777{
2778 xmon_print_symbol(addr, "\t# ", "");
2779}
2780
f312deb4
VS
2781void
2782dump_log_buf(void)
2783{
ca5dd395
ME
2784 struct kmsg_dumper dumper = { .active = 1 };
2785 unsigned char buf[128];
2786 size_t len;
f312deb4 2787
e3bc8049 2788 if (setjmp(bus_error_jmp) != 0) {
ca5dd395 2789 printf("Error dumping printk buffer!\n");
e3bc8049
ME
2790 return;
2791 }
f312deb4 2792
e3bc8049
ME
2793 catch_memory_errors = 1;
2794 sync();
f312deb4 2795
ca5dd395 2796 kmsg_dump_rewind_nolock(&dumper);
0c23a88c 2797 xmon_start_pagination();
ca5dd395
ME
2798 while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2799 buf[len] = '\0';
2800 printf("%s", buf);
2801 }
0c23a88c 2802 xmon_end_pagination();
f312deb4 2803
e3bc8049
ME
2804 sync();
2805 /* wait a little while to see if we get a machine check */
2806 __delay(200);
2807 catch_memory_errors = 0;
f312deb4 2808}
1da177e4 2809
fde93a0f
AD
2810#ifdef CONFIG_PPC_POWERNV
2811static void dump_opal_msglog(void)
2812{
2813 unsigned char buf[128];
2814 ssize_t res;
2815 loff_t pos = 0;
2816
2817 if (!firmware_has_feature(FW_FEATURE_OPAL)) {
2818 printf("Machine is not running OPAL firmware.\n");
2819 return;
2820 }
2821
2822 if (setjmp(bus_error_jmp) != 0) {
2823 printf("Error dumping OPAL msglog!\n");
2824 return;
2825 }
2826
2827 catch_memory_errors = 1;
2828 sync();
2829
2830 xmon_start_pagination();
2831 while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) {
2832 if (res < 0) {
2833 printf("Error dumping OPAL msglog! Error: %zd\n", res);
2834 break;
2835 }
2836 buf[res] = '\0';
2837 printf("%s", buf);
2838 pos += res;
2839 }
2840 xmon_end_pagination();
2841
2842 sync();
2843 /* wait a little while to see if we get a machine check */
2844 __delay(200);
2845 catch_memory_errors = 0;
2846}
2847#endif
2848
1da177e4
LT
2849/*
2850 * Memory operations - move, set, print differences
2851 */
2852static unsigned long mdest; /* destination address */
2853static unsigned long msrc; /* source address */
2854static unsigned long mval; /* byte value to set memory to */
2855static unsigned long mcount; /* # bytes to affect */
2856static unsigned long mdiffs; /* max # differences to print */
2857
9f1067c2 2858static void
1da177e4
LT
2859memops(int cmd)
2860{
2861 scanhex((void *)&mdest);
2862 if( termch != '\n' )
2863 termch = 0;
2864 scanhex((void *)(cmd == 's'? &mval: &msrc));
2865 if( termch != '\n' )
2866 termch = 0;
2867 scanhex((void *)&mcount);
2868 switch( cmd ){
2869 case 'm':
2870 memmove((void *)mdest, (void *)msrc, mcount);
2871 break;
2872 case 's':
2873 memset((void *)mdest, mval, mcount);
2874 break;
2875 case 'd':
2876 if( termch != '\n' )
2877 termch = 0;
2878 scanhex((void *)&mdiffs);
2879 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2880 break;
2881 }
2882}
2883
9f1067c2 2884static void
1da177e4
LT
2885memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2886{
2887 unsigned n, prt;
2888
2889 prt = 0;
2890 for( n = nb; n > 0; --n )
2891 if( *p1++ != *p2++ )
2892 if( ++prt <= maxpr )
e70d8f55 2893 printf("%px %.2x # %px %.2x\n", p1 - 1,
1da177e4
LT
2894 p1[-1], p2 - 1, p2[-1]);
2895 if( prt > maxpr )
2896 printf("Total of %d differences\n", prt);
2897}
2898
2899static unsigned mend;
2900static unsigned mask;
2901
9f1067c2 2902static void
1da177e4
LT
2903memlocate(void)
2904{
2905 unsigned a, n;
2906 unsigned char val[4];
2907
2908 last_cmd = "ml";
2909 scanhex((void *)&mdest);
2910 if (termch != '\n') {
2911 termch = 0;
2912 scanhex((void *)&mend);
2913 if (termch != '\n') {
2914 termch = 0;
2915 scanhex((void *)&mval);
2916 mask = ~0;
2917 if (termch != '\n') termch = 0;
2918 scanhex((void *)&mask);
2919 }
2920 }
2921 n = 0;
2922 for (a = mdest; a < mend; a += 4) {
2923 if (mread(a, val, 4) == 4
2924 && ((GETWORD(val) ^ mval) & mask) == 0) {
2925 printf("%.16x: %.16x\n", a, GETWORD(val));
2926 if (++n >= 10)
2927 break;
2928 }
2929 }
2930}
2931
2932static unsigned long mskip = 0x1000;
2933static unsigned long mlim = 0xffffffff;
2934
9f1067c2 2935static void
1da177e4
LT
2936memzcan(void)
2937{
2938 unsigned char v;
2939 unsigned a;
2940 int ok, ook;
2941
2942 scanhex(&mdest);
2943 if (termch != '\n') termch = 0;
2944 scanhex(&mskip);
2945 if (termch != '\n') termch = 0;
2946 scanhex(&mlim);
2947 ook = 0;
2948 for (a = mdest; a < mlim; a += mskip) {
2949 ok = mread(a, &v, 1);
2950 if (ok && !ook) {
2951 printf("%.8x .. ", a);
1da177e4 2952 } else if (!ok && ook)
e70d8f55 2953 printf("%.8lx\n", a - mskip);
1da177e4
LT
2954 ook = ok;
2955 if (a + mskip < a)
2956 break;
2957 }
2958 if (ook)
e70d8f55 2959 printf("%.8lx\n", a - mskip);
1da177e4
LT
2960}
2961
6dfb5404
DM
2962static void show_task(struct task_struct *tsk)
2963{
2964 char state;
2965
2966 /*
2967 * Cloned from kdb_task_state_char(), which is not entirely
2968 * appropriate for calling from xmon. This could be moved
2969 * to a common, generic, routine used by both.
2970 */
2971 state = (tsk->state == 0) ? 'R' :
2972 (tsk->state < 0) ? 'U' :
2973 (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' :
2974 (tsk->state & TASK_STOPPED) ? 'T' :
2975 (tsk->state & TASK_TRACED) ? 'C' :
2976 (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' :
2977 (tsk->exit_state & EXIT_DEAD) ? 'E' :
2978 (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
2979
d8104182 2980 printf("%px %016lx %6d %6d %c %2d %s\n", tsk,
6dfb5404
DM
2981 tsk->thread.ksp,
2982 tsk->pid, tsk->parent->pid,
2983 state, task_thread_info(tsk)->cpu,
2984 tsk->comm);
2985}
2986
80eff6c4
BS
2987#ifdef CONFIG_PPC_BOOK3S_64
2988void format_pte(void *ptep, unsigned long pte)
2989{
2990 printf("ptep @ 0x%016lx = 0x%016lx\n", (unsigned long)ptep, pte);
2991 printf("Maps physical address = 0x%016lx\n", pte & PTE_RPN_MASK);
2992
2993 printf("Flags = %s%s%s%s%s\n",
2994 (pte & _PAGE_ACCESSED) ? "Accessed " : "",
2995 (pte & _PAGE_DIRTY) ? "Dirty " : "",
2996 (pte & _PAGE_READ) ? "Read " : "",
2997 (pte & _PAGE_WRITE) ? "Write " : "",
2998 (pte & _PAGE_EXEC) ? "Exec " : "");
2999}
3000
3001static void show_pte(unsigned long addr)
3002{
3003 unsigned long tskv = 0;
3004 struct task_struct *tsk = NULL;
3005 struct mm_struct *mm;
3006 pgd_t *pgdp, *pgdir;
3007 pud_t *pudp;
3008 pmd_t *pmdp;
3009 pte_t *ptep;
3010
3011 if (!scanhex(&tskv))
3012 mm = &init_mm;
3013 else
3014 tsk = (struct task_struct *)tskv;
3015
3016 if (tsk == NULL)
3017 mm = &init_mm;
3018 else
3019 mm = tsk->active_mm;
3020
3021 if (setjmp(bus_error_jmp) != 0) {
3022 catch_memory_errors = 0;
d8104182 3023 printf("*** Error dumping pte for task %px\n", tsk);
80eff6c4
BS
3024 return;
3025 }
3026
3027 catch_memory_errors = 1;
3028 sync();
3029
3030 if (mm == &init_mm) {
3031 pgdp = pgd_offset_k(addr);
3032 pgdir = pgd_offset_k(0);
3033 } else {
3034 pgdp = pgd_offset(mm, addr);
3035 pgdir = pgd_offset(mm, 0);
3036 }
3037
3038 if (pgd_none(*pgdp)) {
3039 printf("no linux page table for address\n");
3040 return;
3041 }
3042
e70d8f55 3043 printf("pgd @ 0x%px\n", pgdir);
80eff6c4
BS
3044
3045 if (pgd_huge(*pgdp)) {
3046 format_pte(pgdp, pgd_val(*pgdp));
3047 return;
3048 }
e70d8f55 3049 printf("pgdp @ 0x%px = 0x%016lx\n", pgdp, pgd_val(*pgdp));
80eff6c4
BS
3050
3051 pudp = pud_offset(pgdp, addr);
3052
3053 if (pud_none(*pudp)) {
3054 printf("No valid PUD\n");
3055 return;
3056 }
3057
3058 if (pud_huge(*pudp)) {
3059 format_pte(pudp, pud_val(*pudp));
3060 return;
3061 }
3062
e70d8f55 3063 printf("pudp @ 0x%px = 0x%016lx\n", pudp, pud_val(*pudp));
80eff6c4
BS
3064
3065 pmdp = pmd_offset(pudp, addr);
3066
3067 if (pmd_none(*pmdp)) {
3068 printf("No valid PMD\n");
3069 return;
3070 }
3071
3072 if (pmd_huge(*pmdp)) {
3073 format_pte(pmdp, pmd_val(*pmdp));
3074 return;
3075 }
e70d8f55 3076 printf("pmdp @ 0x%px = 0x%016lx\n", pmdp, pmd_val(*pmdp));
80eff6c4
BS
3077
3078 ptep = pte_offset_map(pmdp, addr);
3079 if (pte_none(*ptep)) {
3080 printf("no valid PTE\n");
3081 return;
3082 }
3083
3084 format_pte(ptep, pte_val(*ptep));
3085
3086 sync();
3087 __delay(200);
3088 catch_memory_errors = 0;
3089}
3090#else
3091static void show_pte(unsigned long addr)
3092{
3093 printf("show_pte not yet implemented\n");
3094}
3095#endif /* CONFIG_PPC_BOOK3S_64 */
3096
6dfb5404
DM
3097static void show_tasks(void)
3098{
3099 unsigned long tskv;
3100 struct task_struct *tsk = NULL;
3101
3102 printf(" task_struct ->thread.ksp PID PPID S P CMD\n");
3103
3104 if (scanhex(&tskv))
3105 tsk = (struct task_struct *)tskv;
3106
3107 if (setjmp(bus_error_jmp) != 0) {
3108 catch_memory_errors = 0;
d8104182 3109 printf("*** Error dumping task %px\n", tsk);
6dfb5404
DM
3110 return;
3111 }
3112
3113 catch_memory_errors = 1;
3114 sync();
3115
3116 if (tsk)
3117 show_task(tsk);
3118 else
3119 for_each_process(tsk)
3120 show_task(tsk);
3121
3122 sync();
3123 __delay(200);
3124 catch_memory_errors = 0;
3125}
3126
9f1067c2 3127static void proccall(void)
f78541dc
PM
3128{
3129 unsigned long args[8];
3130 unsigned long ret;
3131 int i;
3132 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
3133 unsigned long, unsigned long, unsigned long,
3134 unsigned long, unsigned long, unsigned long);
3135 callfunc_t func;
3136
3137 if (!scanhex(&adrs))
3138 return;
3139 if (termch != '\n')
3140 termch = 0;
3141 for (i = 0; i < 8; ++i)
3142 args[i] = 0;
3143 for (i = 0; i < 8; ++i) {
3144 if (!scanhex(&args[i]) || termch == '\n')
3145 break;
3146 termch = 0;
3147 }
3148 func = (callfunc_t) adrs;
3149 ret = 0;
3150 if (setjmp(bus_error_jmp) == 0) {
3151 catch_memory_errors = 1;
3152 sync();
3153 ret = func(args[0], args[1], args[2], args[3],
3154 args[4], args[5], args[6], args[7]);
3155 sync();
736256e4 3156 printf("return value is 0x%lx\n", ret);
f78541dc
PM
3157 } else {
3158 printf("*** %x exception occurred\n", fault_except);
3159 }
3160 catch_memory_errors = 0;
3161}
3162
1da177e4
LT
3163/* Input scanning routines */
3164int
3165skipbl(void)
3166{
3167 int c;
3168
3169 if( termch != 0 ){
3170 c = termch;
3171 termch = 0;
3172 } else
3173 c = inchar();
3174 while( c == ' ' || c == '\t' )
3175 c = inchar();
3176 return c;
3177}
3178
3179#define N_PTREGS 44
0abbf2bf 3180static const char *regnames[N_PTREGS] = {
1da177e4
LT
3181 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
3182 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
3183 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
3184 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
f78541dc
PM
3185 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
3186#ifdef CONFIG_PPC64
3187 "softe",
3188#else
3189 "mq",
3190#endif
1da177e4
LT
3191 "trap", "dar", "dsisr", "res"
3192};
3193
3194int
3195scanhex(unsigned long *vp)
3196{
3197 int c, d;
3198 unsigned long v;
3199
3200 c = skipbl();
3201 if (c == '%') {
3202 /* parse register name */
3203 char regname[8];
3204 int i;
3205
3206 for (i = 0; i < sizeof(regname) - 1; ++i) {
3207 c = inchar();
3208 if (!isalnum(c)) {
3209 termch = c;
3210 break;
3211 }
3212 regname[i] = c;
3213 }
3214 regname[i] = 0;
0abbf2bf
YX
3215 i = match_string(regnames, N_PTREGS, regname);
3216 if (i < 0) {
3217 printf("invalid register name '%%%s'\n", regname);
3218 return 0;
1da177e4 3219 }
0abbf2bf
YX
3220 if (xmon_regs == NULL) {
3221 printf("regs not available\n");
3222 return 0;
3223 }
3224 *vp = ((unsigned long *)xmon_regs)[i];
3225 return 1;
1da177e4
LT
3226 }
3227
3228 /* skip leading "0x" if any */
3229
3230 if (c == '0') {
3231 c = inchar();
3232 if (c == 'x') {
3233 c = inchar();
3234 } else {
3235 d = hexdigit(c);
3236 if (d == EOF) {
3237 termch = c;
3238 *vp = 0;
3239 return 1;
3240 }
3241 }
3242 } else if (c == '$') {
3243 int i;
3244 for (i=0; i<63; i++) {
3245 c = inchar();
05b981f4 3246 if (isspace(c) || c == '\0') {
1da177e4
LT
3247 termch = c;
3248 break;
3249 }
3250 tmpstr[i] = c;
3251 }
3252 tmpstr[i++] = 0;
6879dc13
BH
3253 *vp = 0;
3254 if (setjmp(bus_error_jmp) == 0) {
3255 catch_memory_errors = 1;
3256 sync();
3257 *vp = kallsyms_lookup_name(tmpstr);
3258 sync();
3259 }
3260 catch_memory_errors = 0;
1da177e4
LT
3261 if (!(*vp)) {
3262 printf("unknown symbol '%s'\n", tmpstr);
3263 return 0;
3264 }
3265 return 1;
3266 }
3267
3268 d = hexdigit(c);
3269 if (d == EOF) {
3270 termch = c;
3271 return 0;
3272 }
3273 v = 0;
3274 do {
3275 v = (v << 4) + d;
3276 c = inchar();
3277 d = hexdigit(c);
3278 } while (d != EOF);
3279 termch = c;
3280 *vp = v;
3281 return 1;
3282}
3283
9f1067c2 3284static void
1da177e4
LT
3285scannl(void)
3286{
3287 int c;
3288
3289 c = termch;
3290 termch = 0;
3291 while( c != '\n' )
3292 c = inchar();
3293}
3294
9f1067c2 3295static int hexdigit(int c)
1da177e4
LT
3296{
3297 if( '0' <= c && c <= '9' )
3298 return c - '0';
3299 if( 'A' <= c && c <= 'F' )
3300 return c - ('A' - 10);
3301 if( 'a' <= c && c <= 'f' )
3302 return c - ('a' - 10);
3303 return EOF;
3304}
3305
3306void
3307getstring(char *s, int size)
3308{
3309 int c;
3310
3311 c = skipbl();
3312 do {
3313 if( size > 1 ){
3314 *s++ = c;
3315 --size;
3316 }
3317 c = inchar();
3318 } while( c != ' ' && c != '\t' && c != '\n' );
3319 termch = c;
3320 *s = 0;
3321}
3322
3323static char line[256];
3324static char *lineptr;
3325
9f1067c2 3326static void
1da177e4
LT
3327flush_input(void)
3328{
3329 lineptr = NULL;
3330}
3331
9f1067c2 3332static int
1da177e4
LT
3333inchar(void)
3334{
3335 if (lineptr == NULL || *lineptr == 0) {
fca5dcd4 3336 if (xmon_gets(line, sizeof(line)) == NULL) {
1da177e4
LT
3337 lineptr = NULL;
3338 return EOF;
3339 }
3340 lineptr = line;
3341 }
3342 return *lineptr++;
3343}
3344
9f1067c2 3345static void
1da177e4
LT
3346take_input(char *str)
3347{
3348 lineptr = str;
3349}
3350
3351
3352static void
3353symbol_lookup(void)
3354{
3355 int type = inchar();
3356 unsigned long addr;
3357 static char tmp[64];
3358
3359 switch (type) {
3360 case 'a':
3361 if (scanhex(&addr))
3362 xmon_print_symbol(addr, ": ", "\n");
3363 termch = 0;
3364 break;
3365 case 's':
3366 getstring(tmp, 64);
3367 if (setjmp(bus_error_jmp) == 0) {
3368 catch_memory_errors = 1;
3369 sync();
3370 addr = kallsyms_lookup_name(tmp);
3371 if (addr)
3372 printf("%s: %lx\n", tmp, addr);
3373 else
3374 printf("Symbol '%s' not found.\n", tmp);
3375 sync();
3376 }
3377 catch_memory_errors = 0;
3378 termch = 0;
3379 break;
3380 }
3381}
3382
3383
3384/* Print an address in numeric and symbolic form (if possible) */
3385static void xmon_print_symbol(unsigned long address, const char *mid,
3386 const char *after)
3387{
3388 char *modname;
3389 const char *name = NULL;
3390 unsigned long offset, size;
3391
f78541dc 3392 printf(REG, address);
1da177e4
LT
3393 if (setjmp(bus_error_jmp) == 0) {
3394 catch_memory_errors = 1;
3395 sync();
3396 name = kallsyms_lookup(address, &size, &offset, &modname,
3397 tmpstr);
3398 sync();
3399 /* wait a little while to see if we get a machine check */
3400 __delay(200);
3401 }
3402
3403 catch_memory_errors = 0;
3404
3405 if (name) {
3406 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
3407 if (modname)
3408 printf(" [%s]", modname);
3409 }
3410 printf("%s", after);
3411}
3412
4e003747 3413#ifdef CONFIG_PPC_BOOK3S_64
13b3d13b 3414void dump_segments(void)
1da177e4
LT
3415{
3416 int i;
8218a303 3417 unsigned long esid,vsid;
b3b9595f 3418 unsigned long llp;
1da177e4 3419
736256e4 3420 printf("SLB contents of cpu 0x%x\n", smp_processor_id());
1da177e4 3421
584f8b71 3422 for (i = 0; i < mmu_slb_size; i++) {
b3b9595f 3423 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
3424 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
85673646
ME
3425
3426 if (!esid && !vsid)
3427 continue;
3428
3429 printf("%02d %016lx %016lx", i, esid, vsid);
3430
3431 if (!(esid & SLB_ESID_V)) {
3432 printf("\n");
3433 continue;
3434 }
3435
3436 llp = vsid & SLB_VSID_LLP;
3437 if (vsid & SLB_VSID_B_1T) {
3438 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
3439 GET_ESID_1T(esid),
3440 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
3441 llp);
3442 } else {
3443 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
3444 GET_ESID(esid),
3445 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
3446 llp);
b3b9595f 3447 }
1da177e4
LT
3448 }
3449}
f78541dc
PM
3450#endif
3451
3452#ifdef CONFIG_PPC_STD_MMU_32
3453void dump_segments(void)
3454{
3455 int i;
3456
3457 printf("sr0-15 =");
3458 for (i = 0; i < 16; ++i)
3459 printf(" %x", mfsrin(i));
3460 printf("\n");
3461}
3462#endif
3463
5a8a1a28
BH
3464#ifdef CONFIG_44x
3465static void dump_tlb_44x(void)
3466{
3467 int i;
3468
3469 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
3470 unsigned long w0,w1,w2;
3471 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
3472 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
3473 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
e70d8f55 3474 printf("[%02x] %08lx %08lx %08lx ", i, w0, w1, w2);
5a8a1a28 3475 if (w0 & PPC44x_TLB_VALID) {
e70d8f55 3476 printf("V %08lx -> %01lx%08lx %c%c%c%c%c",
5a8a1a28
BH
3477 w0 & PPC44x_TLB_EPN_MASK,
3478 w1 & PPC44x_TLB_ERPN_MASK,
3479 w1 & PPC44x_TLB_RPN_MASK,
3480 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
3481 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
3482 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
3483 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
3484 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
3485 }
3486 printf("\n");
3487 }
3488}
3489#endif /* CONFIG_44x */
9f1067c2 3490
03247157
BH
3491#ifdef CONFIG_PPC_BOOK3E
3492static void dump_tlb_book3e(void)
3493{
3494 u32 mmucfg, pidmask, lpidmask;
3495 u64 ramask;
3496 int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
3497 int mmu_version;
3498 static const char *pgsz_names[] = {
3499 " 1K",
3500 " 2K",
3501 " 4K",
3502 " 8K",
3503 " 16K",
3504 " 32K",
3505 " 64K",
3506 "128K",
3507 "256K",
3508 "512K",
3509 " 1M",
3510 " 2M",
3511 " 4M",
3512 " 8M",
3513 " 16M",
3514 " 32M",
3515 " 64M",
3516 "128M",
3517 "256M",
3518 "512M",
3519 " 1G",
3520 " 2G",
3521 " 4G",
3522 " 8G",
3523 " 16G",
3524 " 32G",
3525 " 64G",
3526 "128G",
3527 "256G",
3528 "512G",
3529 " 1T",
3530 " 2T",
3531 };
3532
3533 /* Gather some infos about the MMU */
3534 mmucfg = mfspr(SPRN_MMUCFG);
3535 mmu_version = (mmucfg & 3) + 1;
3536 ntlbs = ((mmucfg >> 2) & 3) + 1;
3537 pidsz = ((mmucfg >> 6) & 0x1f) + 1;
3538 lpidsz = (mmucfg >> 24) & 0xf;
3539 rasz = (mmucfg >> 16) & 0x7f;
3540 if ((mmu_version > 1) && (mmucfg & 0x10000))
3541 lrat = 1;
3542 printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
3543 mmu_version, ntlbs, pidsz, lpidsz, rasz);
3544 pidmask = (1ul << pidsz) - 1;
3545 lpidmask = (1ul << lpidsz) - 1;
3546 ramask = (1ull << rasz) - 1;
3547
3548 for (tlb = 0; tlb < ntlbs; tlb++) {
3549 u32 tlbcfg;
3550 int nent, assoc, new_cc = 1;
3551 printf("TLB %d:\n------\n", tlb);
3552 switch(tlb) {
3553 case 0:
3554 tlbcfg = mfspr(SPRN_TLB0CFG);
3555 break;
3556 case 1:
3557 tlbcfg = mfspr(SPRN_TLB1CFG);
3558 break;
3559 case 2:
3560 tlbcfg = mfspr(SPRN_TLB2CFG);
3561 break;
3562 case 3:
3563 tlbcfg = mfspr(SPRN_TLB3CFG);
3564 break;
3565 default:
3566 printf("Unsupported TLB number !\n");
3567 continue;
3568 }
3569 nent = tlbcfg & 0xfff;
3570 assoc = (tlbcfg >> 24) & 0xff;
3571 for (i = 0; i < nent; i++) {
3572 u32 mas0 = MAS0_TLBSEL(tlb);
3573 u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
3574 u64 mas2 = 0;
3575 u64 mas7_mas3;
3576 int esel = i, cc = i;
3577
3578 if (assoc != 0) {
3579 cc = i / assoc;
3580 esel = i % assoc;
3581 mas2 = cc * 0x1000;
3582 }
3583
3584 mas0 |= MAS0_ESEL(esel);
3585 mtspr(SPRN_MAS0, mas0);
3586 mtspr(SPRN_MAS1, mas1);
3587 mtspr(SPRN_MAS2, mas2);
3588 asm volatile("tlbre 0,0,0" : : : "memory");
3589 mas1 = mfspr(SPRN_MAS1);
3590 mas2 = mfspr(SPRN_MAS2);
3591 mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
3592 if (assoc && (i % assoc) == 0)
3593 new_cc = 1;
3594 if (!(mas1 & MAS1_VALID))
3595 continue;
3596 if (assoc == 0)
3597 printf("%04x- ", i);
3598 else if (new_cc)
3599 printf("%04x-%c", cc, 'A' + esel);
3600 else
3601 printf(" |%c", 'A' + esel);
3602 new_cc = 0;
3603 printf(" %016llx %04x %s %c%c AS%c",
3604 mas2 & ~0x3ffull,
3605 (mas1 >> 16) & 0x3fff,
3606 pgsz_names[(mas1 >> 7) & 0x1f],
3607 mas1 & MAS1_IND ? 'I' : ' ',
3608 mas1 & MAS1_IPROT ? 'P' : ' ',
3609 mas1 & MAS1_TS ? '1' : '0');
3610 printf(" %c%c%c%c%c%c%c",
3611 mas2 & MAS2_X0 ? 'a' : ' ',
3612 mas2 & MAS2_X1 ? 'v' : ' ',
3613 mas2 & MAS2_W ? 'w' : ' ',
3614 mas2 & MAS2_I ? 'i' : ' ',
3615 mas2 & MAS2_M ? 'm' : ' ',
3616 mas2 & MAS2_G ? 'g' : ' ',
3617 mas2 & MAS2_E ? 'e' : ' ');
3618 printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
3619 if (mas1 & MAS1_IND)
3620 printf(" %s\n",
3621 pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
3622 else
3623 printf(" U%c%c%c S%c%c%c\n",
3624 mas7_mas3 & MAS3_UX ? 'x' : ' ',
3625 mas7_mas3 & MAS3_UW ? 'w' : ' ',
3626 mas7_mas3 & MAS3_UR ? 'r' : ' ',
3627 mas7_mas3 & MAS3_SX ? 'x' : ' ',
3628 mas7_mas3 & MAS3_SW ? 'w' : ' ',
3629 mas7_mas3 & MAS3_SR ? 'r' : ' ');
3630 }
3631 }
3632}
3633#endif /* CONFIG_PPC_BOOK3E */
3634
9f1067c2 3635static void xmon_init(int enable)
b13cfd17
OH
3636{
3637 if (enable) {
3638 __debugger = xmon;
3639 __debugger_ipi = xmon_ipi;
3640 __debugger_bpt = xmon_bpt;
3641 __debugger_sstep = xmon_sstep;
3642 __debugger_iabr_match = xmon_iabr_match;
9422de3e 3643 __debugger_break_match = xmon_break_match;
b13cfd17
OH
3644 __debugger_fault_handler = xmon_fault_handler;
3645 } else {
3646 __debugger = NULL;
3647 __debugger_ipi = NULL;
3648 __debugger_bpt = NULL;
3649 __debugger_sstep = NULL;
3650 __debugger_iabr_match = NULL;
9422de3e 3651 __debugger_break_match = NULL;
b13cfd17
OH
3652 __debugger_fault_handler = NULL;
3653 }
1da177e4 3654}
fca5dcd4
PM
3655
3656#ifdef CONFIG_MAGIC_SYSRQ
1495cc9d 3657static void sysrq_handle_xmon(int key)
fca5dcd4
PM
3658{
3659 /* ensure xmon is enabled */
3660 xmon_init(1);
7d12e780 3661 debugger(get_irq_regs());
3b5bf42b
PX
3662 if (!xmon_on)
3663 xmon_init(0);
fca5dcd4
PM
3664}
3665
1495cc9d 3666static struct sysrq_key_op sysrq_xmon_op = {
fca5dcd4 3667 .handler = sysrq_handle_xmon,
90a102e5 3668 .help_msg = "xmon(x)",
fca5dcd4
PM
3669 .action_msg = "Entering xmon",
3670};
3671
3672static int __init setup_xmon_sysrq(void)
3673{
3674 register_sysrq_key('x', &sysrq_xmon_op);
3675 return 0;
3676}
b561783c 3677device_initcall(setup_xmon_sysrq);
fca5dcd4 3678#endif /* CONFIG_MAGIC_SYSRQ */
47679283 3679
de78ae6c 3680#ifdef CONFIG_DEBUG_FS
1ff3b404
VJ
3681static void clear_all_bpt(void)
3682{
3683 int i;
3684
3685 /* clear/unpatch all breakpoints */
3686 remove_bpts();
3687 remove_cpu_bpts();
3688
3689 /* Disable all breakpoints */
3690 for (i = 0; i < NBPTS; ++i)
3691 bpts[i].enabled = 0;
3692
3693 /* Clear any data or iabr breakpoints */
3694 if (iabr || dabr.enabled) {
3695 iabr = NULL;
3696 dabr.enabled = 0;
3697 }
3698
3699 printf("xmon: All breakpoints cleared\n");
3700}
3701
de78ae6c
GP
3702static int xmon_dbgfs_set(void *data, u64 val)
3703{
3704 xmon_on = !!val;
3705 xmon_init(xmon_on);
3706
1ff3b404
VJ
3707 /* make sure all breakpoints removed when disabling */
3708 if (!xmon_on)
3709 clear_all_bpt();
de78ae6c
GP
3710 return 0;
3711}
3712
3713static int xmon_dbgfs_get(void *data, u64 *val)
3714{
3715 *val = xmon_on;
3716 return 0;
3717}
3718
3719DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
3720 xmon_dbgfs_set, "%llu\n");
3721
3722static int __init setup_xmon_dbgfs(void)
3723{
3724 debugfs_create_file("xmon", 0600, powerpc_debugfs_root, NULL,
3725 &xmon_dbgfs_ops);
3726 return 0;
3727}
3728device_initcall(setup_xmon_dbgfs);
3729#endif /* CONFIG_DEBUG_FS */
3730
b561783c 3731static int xmon_early __initdata;
47679283
ME
3732
3733static int __init early_parse_xmon(char *p)
3734{
3735 if (!p || strncmp(p, "early", 5) == 0) {
3736 /* just "xmon" is equivalent to "xmon=early" */
3737 xmon_init(1);
3738 xmon_early = 1;
3b5bf42b
PX
3739 xmon_on = 1;
3740 } else if (strncmp(p, "on", 2) == 0) {
47679283 3741 xmon_init(1);
3b5bf42b
PX
3742 xmon_on = 1;
3743 } else if (strncmp(p, "off", 3) == 0)
3744 xmon_on = 0;
47679283
ME
3745 else
3746 return 1;
3747
3748 return 0;
3749}
3750early_param("xmon", early_parse_xmon);
3751
3752void __init xmon_setup(void)
3753{
3b5bf42b 3754 if (xmon_on)
47679283 3755 xmon_init(1);
47679283
ME
3756 if (xmon_early)
3757 debugger(NULL);
3758}
ff8a8f25 3759
e055595d 3760#ifdef CONFIG_SPU_BASE
ff8a8f25
ME
3761
3762struct spu_info {
3763 struct spu *spu;
3764 u64 saved_mfc_sr1_RW;
3765 u32 saved_spu_runcntl_RW;
24a24c85 3766 unsigned long dump_addr;
ff8a8f25
ME
3767 u8 stopped_ok;
3768};
3769
3770#define XMON_NUM_SPUS 16 /* Enough for current hardware */
3771
3772static struct spu_info spu_info[XMON_NUM_SPUS];
3773
3774void xmon_register_spus(struct list_head *list)
3775{
3776 struct spu *spu;
3777
3778 list_for_each_entry(spu, list, full_list) {
3779 if (spu->number >= XMON_NUM_SPUS) {
3780 WARN_ON(1);
3781 continue;
3782 }
3783
3784 spu_info[spu->number].spu = spu;
3785 spu_info[spu->number].stopped_ok = 0;
24a24c85
ME
3786 spu_info[spu->number].dump_addr = (unsigned long)
3787 spu_info[spu->number].spu->local_store;
ff8a8f25
ME
3788 }
3789}
3790
3791static void stop_spus(void)
3792{
3793 struct spu *spu;
3794 int i;
3795 u64 tmp;
3796
3797 for (i = 0; i < XMON_NUM_SPUS; i++) {
3798 if (!spu_info[i].spu)
3799 continue;
3800
3801 if (setjmp(bus_error_jmp) == 0) {
3802 catch_memory_errors = 1;
3803 sync();
3804
3805 spu = spu_info[i].spu;
3806
3807 spu_info[i].saved_spu_runcntl_RW =
3808 in_be32(&spu->problem->spu_runcntl_RW);
3809
3810 tmp = spu_mfc_sr1_get(spu);
3811 spu_info[i].saved_mfc_sr1_RW = tmp;
3812
3813 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3814 spu_mfc_sr1_set(spu, tmp);
3815
3816 sync();
3817 __delay(200);
3818
3819 spu_info[i].stopped_ok = 1;
2a14442b
ME
3820
3821 printf("Stopped spu %.2d (was %s)\n", i,
3822 spu_info[i].saved_spu_runcntl_RW ?
3823 "running" : "stopped");
ff8a8f25
ME
3824 } else {
3825 catch_memory_errors = 0;
3826 printf("*** Error stopping spu %.2d\n", i);
3827 }
3828 catch_memory_errors = 0;
3829 }
3830}
3831
3832static void restart_spus(void)
3833{
3834 struct spu *spu;
3835 int i;
3836
3837 for (i = 0; i < XMON_NUM_SPUS; i++) {
3838 if (!spu_info[i].spu)
3839 continue;
3840
3841 if (!spu_info[i].stopped_ok) {
3842 printf("*** Error, spu %d was not successfully stopped"
3843 ", not restarting\n", i);
3844 continue;
3845 }
3846
3847 if (setjmp(bus_error_jmp) == 0) {
3848 catch_memory_errors = 1;
3849 sync();
3850
3851 spu = spu_info[i].spu;
3852 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3853 out_be32(&spu->problem->spu_runcntl_RW,
3854 spu_info[i].saved_spu_runcntl_RW);
3855
3856 sync();
3857 __delay(200);
3858
3859 printf("Restarted spu %.2d\n", i);
3860 } else {
3861 catch_memory_errors = 0;
3862 printf("*** Error restarting spu %.2d\n", i);
3863 }
3864 catch_memory_errors = 0;
3865 }
3866}
3867
a8984970 3868#define DUMP_WIDTH 23
437a0706 3869#define DUMP_VALUE(format, field, value) \
a8984970
ME
3870do { \
3871 if (setjmp(bus_error_jmp) == 0) { \
3872 catch_memory_errors = 1; \
3873 sync(); \
3874 printf(" %-*s = "format"\n", DUMP_WIDTH, \
437a0706 3875 #field, value); \
a8984970
ME
3876 sync(); \
3877 __delay(200); \
3878 } else { \
3879 catch_memory_errors = 0; \
3880 printf(" %-*s = *** Error reading field.\n", \
3881 DUMP_WIDTH, #field); \
3882 } \
3883 catch_memory_errors = 0; \
3884} while (0)
3885
437a0706
ME
3886#define DUMP_FIELD(obj, format, field) \
3887 DUMP_VALUE(format, field, obj->field)
3888
a8984970
ME
3889static void dump_spu_fields(struct spu *spu)
3890{
3891 printf("Dumping spu fields at address %p:\n", spu);
3892
3893 DUMP_FIELD(spu, "0x%x", number);
3894 DUMP_FIELD(spu, "%s", name);
a8984970
ME
3895 DUMP_FIELD(spu, "0x%lx", local_store_phys);
3896 DUMP_FIELD(spu, "0x%p", local_store);
3897 DUMP_FIELD(spu, "0x%lx", ls_size);
3898 DUMP_FIELD(spu, "0x%x", node);
3899 DUMP_FIELD(spu, "0x%lx", flags);
e70d8f55
MM
3900 DUMP_FIELD(spu, "%llu", class_0_pending);
3901 DUMP_FIELD(spu, "0x%llx", class_0_dar);
3902 DUMP_FIELD(spu, "0x%llx", class_1_dar);
3903 DUMP_FIELD(spu, "0x%llx", class_1_dsisr);
3904 DUMP_FIELD(spu, "0x%x", irqs[0]);
3905 DUMP_FIELD(spu, "0x%x", irqs[1]);
3906 DUMP_FIELD(spu, "0x%x", irqs[2]);
a8984970
ME
3907 DUMP_FIELD(spu, "0x%x", slb_replace);
3908 DUMP_FIELD(spu, "%d", pid);
a8984970
ME
3909 DUMP_FIELD(spu, "0x%p", mm);
3910 DUMP_FIELD(spu, "0x%p", ctx);
3911 DUMP_FIELD(spu, "0x%p", rq);
e70d8f55 3912 DUMP_FIELD(spu, "0x%llx", timestamp);
a8984970
ME
3913 DUMP_FIELD(spu, "0x%lx", problem_phys);
3914 DUMP_FIELD(spu, "0x%p", problem);
437a0706
ME
3915 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3916 in_be32(&spu->problem->spu_runcntl_RW));
3917 DUMP_VALUE("0x%x", problem->spu_status_R,
3918 in_be32(&spu->problem->spu_status_R));
3919 DUMP_VALUE("0x%x", problem->spu_npc_RW,
3920 in_be32(&spu->problem->spu_npc_RW));
a8984970 3921 DUMP_FIELD(spu, "0x%p", priv2);
a985239b 3922 DUMP_FIELD(spu, "0x%p", pdata);
a8984970
ME
3923}
3924
af89fb80
ME
3925int
3926spu_inst_dump(unsigned long adr, long count, int praddr)
3927{
3928 return generic_inst_dump(adr, count, praddr, print_insn_spu);
3929}
3930
3931static void dump_spu_ls(unsigned long num, int subcmd)
24a24c85
ME
3932{
3933 unsigned long offset, addr, ls_addr;
3934
3935 if (setjmp(bus_error_jmp) == 0) {
3936 catch_memory_errors = 1;
3937 sync();
3938 ls_addr = (unsigned long)spu_info[num].spu->local_store;
3939 sync();
3940 __delay(200);
3941 } else {
3942 catch_memory_errors = 0;
e70d8f55 3943 printf("*** Error: accessing spu info for spu %ld\n", num);
24a24c85
ME
3944 return;
3945 }
3946 catch_memory_errors = 0;
3947
3948 if (scanhex(&offset))
3949 addr = ls_addr + offset;
3950 else
3951 addr = spu_info[num].dump_addr;
3952
3953 if (addr >= ls_addr + LS_SIZE) {
3954 printf("*** Error: address outside of local store\n");
3955 return;
3956 }
3957
af89fb80
ME
3958 switch (subcmd) {
3959 case 'i':
3960 addr += spu_inst_dump(addr, 16, 1);
3961 last_cmd = "sdi\n";
3962 break;
3963 default:
3964 prdump(addr, 64);
3965 addr += 64;
3966 last_cmd = "sd\n";
3967 break;
3968 }
24a24c85
ME
3969
3970 spu_info[num].dump_addr = addr;
3971}
3972
ff8a8f25
ME
3973static int do_spu_cmd(void)
3974{
24a24c85 3975 static unsigned long num = 0;
af89fb80 3976 int cmd, subcmd = 0;
ff8a8f25
ME
3977
3978 cmd = inchar();
3979 switch (cmd) {
3980 case 's':
3981 stop_spus();
3982 break;
3983 case 'r':
3984 restart_spus();
3985 break;
24a24c85 3986 case 'd':
af89fb80
ME
3987 subcmd = inchar();
3988 if (isxdigit(subcmd) || subcmd == '\n')
3989 termch = subcmd;
3990 case 'f':
24a24c85
ME
3991 scanhex(&num);
3992 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
a8984970 3993 printf("*** Error: invalid spu number\n");
24a24c85
ME
3994 return 0;
3995 }
3996
3997 switch (cmd) {
3998 case 'f':
3999 dump_spu_fields(spu_info[num].spu);
4000 break;
4001 default:
af89fb80 4002 dump_spu_ls(num, subcmd);
24a24c85
ME
4003 break;
4004 }
4005
a8984970 4006 break;
ff8a8f25
ME
4007 default:
4008 return -1;
4009 }
4010
4011 return 0;
4012}
e055595d 4013#else /* ! CONFIG_SPU_BASE */
ff8a8f25
ME
4014static int do_spu_cmd(void)
4015{
4016 return -1;
4017}
4018#endif