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