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