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