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