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