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