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