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

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

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

~ [ 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