~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/xmon/xmon.c

Version: ~ [ linux-4.17-rc1 ] ~ [ linux-4.16.2 ] ~ [ linux-4.15.17 ] ~ [ linux-4.14.34 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.94 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.128 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.51 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.105 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.56 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.101 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp