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