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

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

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

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