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