11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Routines providing a simple monitor for use on the PowerMac.
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras * Copyright (C) 1996-2005 Paul Mackerras.
5476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman * Copyright (C) 2001 PPC64 Team, IBM Corp
6476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman * Copyrignt (C) 2006 Michael Ellerman, IBM Corp
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      This program is free software; you can redistribute it and/or
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      modify it under the terms of the GNU General Public License
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      as published by the Free Software Foundation; either version
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      2 of the License, or (at your option) any later version.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/smp.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/reboot.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kallsyms.h>
20ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman#include <linux/kmsg_dump.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/cpumask.h>
224b16f8e2d6d64249f0ed3ca7fe2a319d0dde2719Paul Gortmaker#include <linux/export.h>
23fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#include <linux/sysrq.h>
244694ca02d19f42f5fd0b62cc2d0c7d3e5a0eef47Andrew Morton#include <linux/interrupt.h>
257d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells#include <linux/irq.h>
2673c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge#include <linux/bug.h>
27a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard#include <linux/nmi.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ptrace.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/string.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/prom.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/machdep.h>
33f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#include <asm/xmon.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/processor.h>
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mmu_context.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/cputable.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/rtas.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sstep.h>
41f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerras#include <asm/irq_regs.h>
42ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#include <asm/spu.h>
43ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#include <asm/spu_priv1.h>
44c3b75bd7bbf4a0438dc140033b80657995fd30edMichael Neuling#include <asm/setjmp.h>
45322b439455ea62e6480e300c77b258e872896381Anton Vorontsov#include <asm/reg.h>
46ae3a197e3d0bfe3f4bf1693723e82dc018c096f3David Howells#include <asm/debug.h>
479422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling#include <asm/hw_breakpoint.h>
48f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
49f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/hvcall.h>
51f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#include <asm/paca.h>
52f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "nonstdio.h"
55e0426047cb684842700f0098f74842a38260dbaeMichael Ellerman#include "dis-asm.h"
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
581c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellermanstatic cpumask_t cpus_in_xmon = CPU_MASK_NONE;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long xmon_taken = 1;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_owner;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_gate;
62ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#else
63ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#define xmon_owner 0
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
665be3492f972b73051ead7ecbac6fb9efd1e8e0ecAnton Blanchardstatic unsigned long in_xmon __read_mostly = 0;
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long adrs;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int size = 1;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_DUMP (128 * 1024)
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long ndump = 64;
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long nidump = 16;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long ncsum = 4096;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int termch;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char tmpstr[128];
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long bus_error_jmp[JMP_BUF_LEN];
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int catch_memory_errors;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long *xmon_fault_jmp[NR_CPUS];
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Breakpoint stuff */
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bpt {
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long	address;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int	instr[2];
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	atomic_t	ref_count;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int		enabled;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long	pad;
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Bits in bpt.enabled */
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_IABR_TE	1		/* IABR translation enabled */
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_IABR		2
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_TRAP		8
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_DABR		0x10
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define NBPTS	256
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt bpts[NBPTS];
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt dabr;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *iabr;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned bpinstr = 0x7fe00008;	/* trap */
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BP_NUM(bp)	((bp) - bpts + 1)
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Prototypes */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cmds(struct pt_regs *);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mread(unsigned long, void *, int);
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mwrite(unsigned long, void *, int);
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int handle_fault(struct pt_regs *);
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void byterev(unsigned char *, int);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memex(void);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int bsesc(void);
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void dump(void);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void prdump(unsigned long, long);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ppc_inst_dump(unsigned long, long, int);
115f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridharstatic void dump_log_buf(void);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void backtrace(struct pt_regs *);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void excprint(struct pt_regs *);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void prregs(struct pt_regs *);
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memops(int);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memlocate(void);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memzcan(void);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint skipbl(void);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint scanhex(unsigned long *valp);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void scannl(void);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hexdigit(int);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid getstring(char *, int);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void flush_input(void);
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int inchar(void);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void take_input(char *);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long read_spr(int);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_spr(int, unsigned long);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void super_regs(void);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_bpts(void);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_bpts(void);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_cpu_bpts(void);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_cpu_bpts(void);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *at_breakpoint(unsigned long pc);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int  do_step(struct pt_regs *);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bpt_cmds(void);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void cacheflush(void);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int  cpu_cmd(void);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void csum(void);
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bootcmds(void);
146f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic void proccall(void);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid dump_segments(void);
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void symbol_lookup(void);
14926c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Heringstatic void xmon_show_stack(unsigned long sp, unsigned long lr,
15026c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering			    unsigned long pc);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_print_symbol(unsigned long address, const char *mid,
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      const char *after);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *getvecname(unsigned long vec);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
155ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void);
156ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
1575a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#ifdef CONFIG_44x
1585a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidtstatic void dump_tlb_44x(void);
1595a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif
16003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E
16103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidtstatic void dump_tlb_book3e(void);
16203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif
1635a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt
1649f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int xmon_no_auto_backtrace;
16526c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering
166f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasextern void xmon_enter(void);
167f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasextern void xmon_leave(void);
168f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
169f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64
170f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#define REG		"%.16lx"
171f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else
172f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#define REG		"%.8lx"
173f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17572eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#ifdef __LITTLE_ENDIAN__
17672eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#define GETWORD(v)	(((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
17772eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#else
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define GETWORD(v)	(((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
17972eceef67abbe596a4e93ee79e08d9e6c35430aePhilippe Bergheaud#endif
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('a' <= (c) && (c) <= 'f') \
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('A' <= (c) && (c) <= 'F'))
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isalnum(c)	(('0' <= (c) && (c) <= '9') \
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('a' <= (c) && (c) <= 'z') \
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('A' <= (c) && (c) <= 'Z'))
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isspace(c)	(c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *help_string = "\
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsCommands:\n\
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  b	show breakpoints\n\
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  bd	set data breakpoint\n\
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  bi	set instruction breakpoint\n\
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  bc	clear breakpoint\n"
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  "\
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  c	print cpus stopped in xmon\n\
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  c#	try to switch to cpu number h (in hex)\n"
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  "\
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  C	checksum\n\
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  d	dump bytes\n\
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  di	dump instructions\n\
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  df	dump float values\n\
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  dd	dump double values\n\
206ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman  dl    dump the kernel log buffer\n"
207ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64
208ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman  "\
209ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman  dp[#]	dump paca for current cpu, or cpu #\n\
210ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman  dpa	dump paca for all possible cpus\n"
211ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif
212ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman  "\
2137e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering  dr	dump stream of raw bytes\n\
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  e	print exception information\n\
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  f	flush cache\n\
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  la	lookup symbol+offset of specified address\n\
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  ls	lookup address of specified symbol\n\
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  m	examine/change memory\n\
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  mm	move a block of memory\n\
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  ms	set a block of memory\n\
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  md	compare two blocks of memory\n\
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  ml	locate a block of memory\n\
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  mz	zero a block of memory\n\
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  mi	show information about memory allocation\n\
225f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras  p 	call a procedure\n\
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  r	print registers\n\
227ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman  s	single step\n"
228e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#ifdef CONFIG_SPU_BASE
229ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman"  ss	stop execution on all spus\n\
230a898497088f46252e6750405504064e2dce53117Michael Ellerman  sr	restore execution on stopped spus\n\
23124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman  sf  #	dump spu fields for spu # (in hex)\n\
232c99176a230097b076c2f98e4bf963399fe114ffdMichael Ellerman  sd  #	dump spu local store for spu # (in hex)\n\
233af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman  sdi #	disassemble spu local store for spu # (in hex)\n"
234ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#endif
235ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman"  S	print special registers\n\
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  t	print backtrace\n\
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  x	exit monitor and recover\n\
238f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras  X	exit monitor and dont recover\n"
23979873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E)
240f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras"  u	dump segment table or SLB\n"
24179873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_PPC_STD_MMU_32)
242f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras"  u	dump segment registers\n"
24379873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_44x) || defined(CONFIG_PPC_BOOK3E)
2445a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt"  u	dump TLB\n"
2455a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif
246f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras"  ?	help\n"
247f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras"  zr	reboot\n\
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  zh	halt\n"
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds;
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pt_regs *xmon_regs;
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
253f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void sync(void)
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm volatile("sync; isync");
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
258f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void store_inst(void *p)
259f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
260f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
261f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
262f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
263f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void cflush(void *p)
264f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
265f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
266f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
267f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
268f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic inline void cinval(void *p)
269f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
270f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
271f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Disable surveillance (the service processor watchdog function)
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * while we are in xmon.
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XXX we should re-enable it when we leave. :)
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SURVEILLANCE_TOKEN	9000
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void disable_surveillance(void)
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PPC_PSERIES
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Since this can't be a module, args should end up below 4GB. */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static struct rtas_args args;
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * At this point we have got all the cpus we can into
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * xmon, so there is hopefully no other cpu calling RTAS
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * at the moment, even though we don't take rtas.lock.
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If we did try to take rtas.lock there would be a
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * real possibility of deadlock.
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	args.token = rtas_token("set-indicator");
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (args.token == RTAS_UNKNOWN_SERVICE)
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
2963b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour	args.nargs = cpu_to_be32(3);
2973b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour	args.nret = cpu_to_be32(1);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	args.rets = &args.args[3];
2993b8a3c01096925a824ed3272601082289d9c23a5Laurent Dufour	args.args[0] = cpu_to_be32(SURVEILLANCE_TOKEN);
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	args.args[1] = 0;
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	args.args[2] = 0;
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	enter_rtas(__pa(&args));
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_PPC_PSERIES */
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int xmon_speaker;
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void get_output_lock(void)
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int me = smp_processor_id() + 0x100;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int last_speaker = 0, prev;
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long timeout;
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (xmon_speaker == me)
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
317730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (;;) {
319730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman		last_speaker = cmpxchg(&xmon_speaker, 0, me);
320730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman		if (last_speaker == 0)
321730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman			return;
322730efb6193f8568354fd80849612291afa9fa81eMichael Ellerman
3231507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman		/*
3241507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman		 * Wait a full second for the lock, we might be on a slow
3251507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman		 * console, but check every 100us.
3261507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman		 */
3271507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman		timeout = 10000;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while (xmon_speaker == last_speaker) {
3291507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman			if (--timeout > 0) {
3301507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman				udelay(100);
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
3321507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman			}
3331507589787529b0d8e2a9e66e0c6f113ecab5181Michael Ellerman
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* hostile takeover */
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			prev = cmpxchg(&xmon_speaker, last_speaker, me);
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (prev == last_speaker)
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void release_output_lock(void)
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_speaker = 0;
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3471c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman
3481c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellermanint cpus_are_in_xmon(void)
3491c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman{
350104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro	return !cpumask_empty(&cpus_in_xmon);
3511c8950ff87de950a3b6ccfb26650fc0a56278836Michael Ellerman}
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
354daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyerstatic inline int unrecoverable_excp(struct pt_regs *regs)
355daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer{
35608f6d6abc3eadb88f020075910e6f3a849e56690Jimi Xenidis#if defined(CONFIG_4xx) || defined(CONFIG_PPC_BOOK3E)
35766857b3a9e88ac6f6e279eaa06b84367e662c0ddJimi Xenidis	/* We have no MSR_RI bit on 4xx or Book3e, so we simply return false */
358daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer	return 0;
359daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer#else
360daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer	return ((regs->msr & MSR_RI) == 0);
361daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer#endif
362daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer}
363daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer
364b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_core(struct pt_regs *regs, int fromipi)
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd = 0;
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long recurse_jmp[JMP_BUF_LEN];
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long offset;
370f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard	unsigned long flags;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cpu;
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int secondary;
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long timeout;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
377f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard	local_irq_save(flags);
378a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard	hard_irq_disable();
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = in_breakpoint_table(regs->nip, &offset);
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bp != NULL) {
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		regs->nip = bp->address + offset;
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&bp->ref_count);
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	remove_cpu_bpts();
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cpu = smp_processor_id();
390104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro	if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		get_output_lock();
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		excprint(regs);
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("cpu 0x%x: Exception %lx %s in xmon, "
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "returning to main loop\n",
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       cpu, regs->trap, getvecname(TRAP(regs)));
3965cb4cc0d8211c490537c8568001958fc76741312Haren Myneni		release_output_lock();
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		longjmp(xmon_fault_jmp[cpu], 1);
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(recurse_jmp) != 0) {
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!in_xmon || !xmon_gate) {
4025cb4cc0d8211c490537c8568001958fc76741312Haren Myneni			get_output_lock();
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("xmon: WARNING: bad recursive fault "
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "on cpu 0x%x\n", cpu);
4055cb4cc0d8211c490537c8568001958fc76741312Haren Myneni			release_output_lock();
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto waiting;
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		secondary = !(xmon_taken && cpu == xmon_owner);
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cmdloop;
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_fault_jmp[cpu] = recurse_jmp;
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = NULL;
4159f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = at_breakpoint(regs->nip);
417daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer	if (bp || unrecoverable_excp(regs))
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fromipi = 0;
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!fromipi) {
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		get_output_lock();
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		excprint(regs);
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp) {
424736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman			printf("cpu 0x%x stopped at breakpoint 0x%lx (",
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       cpu, BP_NUM(bp));
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_print_symbol(regs->nip, " ", ")\n");
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
428daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer		if (unrecoverable_excp(regs))
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("WARNING: exception is not recoverable, "
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "can't continue\n");
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		release_output_lock();
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
434d2b496e5e1fa7a6796534e435440eb9d3ed184ddMichael Ellerman	cpumask_set_cpu(cpu, &cpus_in_xmon);
435d2b496e5e1fa7a6796534e435440eb9d3ed184ddMichael Ellerman
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds waiting:
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	secondary = 1;
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (secondary && !xmon_gate) {
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (in_xmon == 0) {
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (fromipi)
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				goto leave;
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			secondary = test_and_set_bit(0, &in_xmon);
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		barrier();
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!secondary && !xmon_gate) {
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* we are the first cpu to come in */
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* interrupt other cpu(s) */
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int ncpus = num_online_cpus();
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_owner = cpu;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb();
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ncpus > 1) {
455e04763713286b1e00e1c2a33fe2741caf9470f2bMilton Miller			smp_send_debugger_break();
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* wait for other cpus to come in */
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (timeout = 100000000; timeout != 0; --timeout) {
458104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro				if (cpumask_weight(&cpus_in_xmon) >= ncpus)
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					break;
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				barrier();
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		remove_bpts();
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		disable_surveillance();
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* for breakpoint or single step, print the current instr. */
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp || TRAP(regs) == 0xd00)
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ppc_inst_dump(regs->nip, 1, 0);
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("enter ? for help\n");
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mb();
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_gate = 1;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		barrier();
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmdloop:
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (in_xmon) {
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (secondary) {
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cpu == xmon_owner) {
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!test_and_set_bit(0, &xmon_taken)) {
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					secondary = 0;
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					continue;
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* missed it */
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				while (cpu == xmon_owner)
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					barrier();
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			barrier();
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cmd = cmds(regs);
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cmd != 0) {
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* exiting xmon */
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				insert_bpts();
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				xmon_gate = 0;
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				wmb();
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				in_xmon = 0;
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* have switched to some other cpu */
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			secondary = 1;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds leave:
502104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro	cpumask_clear_cpu(cpu, &cpus_in_xmon);
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_fault_jmp[cpu] = NULL;
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* UP is simple... */
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (in_xmon) {
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("Exception %lx %s in xmon, returning to main loop\n",
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       regs->trap, getvecname(TRAP(regs)));
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		longjmp(xmon_fault_jmp[0], 1);
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(recurse_jmp) == 0) {
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_fault_jmp[0] = recurse_jmp;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		in_xmon = 1;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		excprint(regs);
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = at_breakpoint(regs->nip);
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp) {
518736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman			printf("Stopped at breakpoint %lx (", BP_NUM(bp));
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_print_symbol(regs->nip, " ", ")\n");
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
521daf8f40391b2a1978ea2071c20959d91fade6b1aJosh Boyer		if (unrecoverable_excp(regs))
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("WARNING: exception is not recoverable, "
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "can't continue\n");
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		remove_bpts();
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		disable_surveillance();
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* for breakpoint or single step, print the current instr. */
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp || TRAP(regs) == 0xd00)
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ppc_inst_dump(regs->nip, 1, 0);
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("enter ? for help\n");
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = cmds(regs);
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	insert_bpts();
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	in_xmon = 0;
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
538cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#ifdef CONFIG_BOOKE
539cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer	if (regs->msr & MSR_DE) {
540cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer		bp = at_breakpoint(regs->nip);
541cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer		if (bp != NULL) {
542cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer			regs->nip = (unsigned long) &bp->instr[0];
543cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer			atomic_inc(&bp->ref_count);
544cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer		}
545cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer	}
546cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#else
5479f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = at_breakpoint(regs->nip);
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp != NULL) {
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int stepped = emulate_step(regs, bp->instr[0]);
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (stepped == 0) {
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				regs->nip = (unsigned long) &bp->instr[0];
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				atomic_inc(&bp->ref_count);
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (stepped < 0) {
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("Couldn't single-step %s instruction\n",
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
560cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#endif
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	insert_cpu_bpts();
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
563a71d64b4dc4067808549935583d984c7fc9ea647Anton Blanchard	touch_nmi_watchdog();
564f13659e0b3907548402ce1f47bf866544b804260Anton Blanchard	local_irq_restore(flags);
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5660a730ae59960165ae50de3284fb50316d1755d98Paul Mackerras	return cmd != 'X' && cmd != EOF;
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint xmon(struct pt_regs *excp)
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pt_regs regs;
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (excp == NULL) {
574322b439455ea62e6480e300c77b258e872896381Anton Vorontsov		ppc_save_regs(&regs);
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		excp = &regs;
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
577ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return xmon_core(excp, 0);
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
580f78541dcec327b0c46b150ee7d727f3db80275c4Paul MackerrasEXPORT_SYMBOL(xmon);
581f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
582f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerrasirqreturn_t xmon_irq(int irq, void *d)
583f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
584f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	unsigned long flags;
585f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	local_irq_save(flags);
586f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf("Keyboard interrupt\n");
587f583ffce1aac783fd16d5d75cd69ac5ebb8f4933Paul Mackerras	xmon(get_irq_regs());
588f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	local_irq_restore(flags);
589f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	return IRQ_HANDLED;
590f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
592b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_bpt(struct pt_regs *regs)
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long offset;
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5979f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Are we at the trap at bp->instr[1] for some bp? */
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = in_breakpoint_table(regs->nip, &offset);
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bp != NULL && offset == 4) {
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		regs->nip = bp->address + 4;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&bp->ref_count);
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Are we at a breakpoint? */
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = at_breakpoint(regs->nip);
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!bp)
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_core(regs, 0);
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
618b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_sstep(struct pt_regs *regs)
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (user_mode(regs))
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_core(regs, 0);
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6269422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neulingstatic int xmon_break_match(struct pt_regs *regs)
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6289f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
630fd9648dff6f9797ecc509bcd181706a274dc074dAnton Blanchard	if (dabr.enabled == 0)
631fd9648dff6f9797ecc509bcd181706a274dc074dAnton Blanchard		return 0;
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_core(regs, 0);
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
636b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_iabr_match(struct pt_regs *regs)
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6389f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
6409f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman	if (iabr == NULL)
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_core(regs, 0);
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
646b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_ipi(struct pt_regs *regs)
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
649104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro	if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_core(regs, 1);
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
655b0da985644faa45def84ce5d8e18af6f1680f490Arnd Bergmannstatic int xmon_fault_handler(struct pt_regs *regs)
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long offset;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (in_xmon && catch_memory_errors)
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		handle_fault(regs);	/* doesn't return */
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6639f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = in_breakpoint_table(regs->nip, &offset);
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp != NULL) {
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			regs->nip = bp->address + offset;
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_dec(&bp->ref_count);
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *at_breakpoint(unsigned long pc)
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = bpts;
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < NBPTS; ++i, ++bp)
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp->enabled && pc == bp->address)
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return bp;
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return NULL;
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long off;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	off = nip - (unsigned long) bpts;
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (off >= sizeof(bpts))
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	off %= sizeof(struct bpt);
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (off != offsetof(struct bpt, instr[0])
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    && off != offsetof(struct bpt, instr[1]))
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*offp = off - offsetof(struct bpt, instr[0]);
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (struct bpt *) (nip - off);
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct bpt *new_breakpoint(unsigned long a)
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a &= ~3UL;
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = at_breakpoint(a);
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bp)
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return bp;
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->address = a;
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->instr[1] = bpinstr;
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			store_inst(&bp->instr[1]);
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return bp;
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("Sorry, no free breakpoints.  Please clear one first.\n");
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return NULL;
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_bpts(void)
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = bpts;
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < NBPTS; ++i, ++bp) {
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mread(bp->address, &bp->instr[0], 4) != 4) {
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Couldn't read instruction at %lx, "
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "disabling breakpoint there\n", bp->address);
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->enabled = 0;
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Breakpoint at %lx is on an mtmsrd or rfid "
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "instruction, disabling it\n", bp->address);
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->enabled = 0;
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		store_inst(&bp->instr[0]);
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp->enabled & BP_IABR)
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mwrite(bp->address, &bpinstr, 4) != 4) {
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Couldn't write instruction at %lx, "
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "disabling breakpoint there\n", bp->address);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->enabled &= ~BP_TRAP;
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		store_inst((void *)bp->address);
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void insert_cpu_bpts(void)
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7599422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling	struct arch_hw_breakpoint brk;
7609422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling
7619422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling	if (dabr.enabled) {
7629422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling		brk.address = dabr.address;
7639422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling		brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
7649422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling		brk.len = 8;
76521f585073d6347651f2262da187606fa1c4ee16dPaul Gortmaker		__set_breakpoint(&brk);
7669422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling	}
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (iabr && cpu_has_feature(CPU_FTR_IABR))
768f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		mtspr(SPRN_IABR, iabr->address
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_bpts(void)
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned instr;
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = bpts;
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < NBPTS; ++i, ++bp) {
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mread(bp->address, &instr, 4) == 4
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    && instr == bpinstr
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    && mwrite(bp->address, &bp->instr, 4) != 4)
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Couldn't remove breakpoint at %lx\n",
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       bp->address);
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			store_inst((void *)bp->address);
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void remove_cpu_bpts(void)
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7949422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling	hw_breakpoint_disable();
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cpu_has_feature(CPU_FTR_IABR))
796f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		mtspr(SPRN_IABR, 0);
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Command interpreting routine */
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *last_cmd;
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscmds(struct pt_regs *excp)
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd = 0;
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	last_cmd = NULL;
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_regs = excp;
80926c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering
81026c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering	if (!xmon_no_auto_backtrace) {
81126c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering		xmon_no_auto_backtrace = 1;
81226c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
81326c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering	}
81426c8af5f01dfb91f709cc2ba07fb650949aae13eOlaf Hering
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(;;) {
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("%x:", smp_processor_id());
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("mon> ");
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		flush_input();
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cmd = skipbl();
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( cmd == '\n' ) {
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (last_cmd == NULL)
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				continue;
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			take_input(last_cmd);
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			last_cmd = NULL;
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cmd = inchar();
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (cmd) {
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'm':
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cmd = inchar();
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch (cmd) {
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'm':
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 's':
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'd':
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				memops(cmd);
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'l':
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				memlocate();
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'z':
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				memzcan();
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'i':
846b2b755b5f10eb32fbdc73a9907c07006b17f714bDavid Rientjes				show_mem(0);
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			default:
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				termch = cmd;
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				memex();
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'd':
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dump();
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'l':
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			symbol_lookup();
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'r':
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			prregs(excp);	/* print regs */
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'e':
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			excprint(excp);
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'S':
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			super_regs();
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 't':
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			backtrace(excp);
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'f':
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cacheflush();
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 's':
875ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			if (do_spu_cmd() == 0)
876ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman				break;
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (do_step(excp))
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return cmd;
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'x':
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'X':
882bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt			return cmd;
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case EOF:
884bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt			printf(" <no input ...>\n");
885bb6b9b28d6847bc71f910e2e82c9040ff4b97ec0Benjamin Herrenschmidt			mdelay(2000);
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return cmd;
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case '?':
8884d404edce30f911004850d472e05a31efd751662Ishizaki Kou			xmon_puts(help_string);
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'b':
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bpt_cmds();
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'C':
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			csum();
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'c':
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cpu_cmd())
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 0;
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'z':
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bootcmds();
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
903f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		case 'p':
904f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			proccall();
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
906f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC_STD_MMU
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'u':
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dump_segments();
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
91079873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_4xx)
9115a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		case 'u':
9125a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			dump_tlb_44x();
9135a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			break;
91479873e8df64cc124cdcad56d1d8330b3f45690bcJimi Xenidis#elif defined(CONFIG_PPC_BOOK3E)
91503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		case 'u':
91603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			dump_tlb_book3e();
91703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			break;
91803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Unrecognized command: ");
921e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman			do {
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (' ' < cmd && cmd <= '~')
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					putchar(cmd);
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf("\\x%x", cmd);
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				cmd = inchar();
927e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman			} while (cmd != '\n');
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf(" (type ? for help)\n");
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
934cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#ifdef CONFIG_BOOKE
935cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyerstatic int do_step(struct pt_regs *regs)
936cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer{
937cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer	regs->msr |= MSR_DE;
938cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer	mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
939cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer	return 1;
940cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer}
941cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#else
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Step a single instruction.
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some instructions we emulate, others we execute with MSR_SE set.
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_step(struct pt_regs *regs)
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int instr;
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stepped;
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* check we are in 64-bit kernel mode, translation enabled */
9529f0b079320ad1cc71ad7ea4e0ed0b64cd72bbd6dMichael Ellerman	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mread(regs->nip, &instr, 4) == 4) {
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stepped = emulate_step(regs, instr);
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (stepped < 0) {
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("Couldn't single-step %s instruction\n",
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				       (IS_RFID(instr)? "rfid": "mtmsrd"));
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 0;
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (stepped > 0) {
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				regs->trap = 0xd00 | (regs->trap & 1);
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("stepped to ");
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				xmon_print_symbol(regs->nip, " ", "\n");
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				ppc_inst_dump(regs->nip, 1, 0);
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 0;
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	regs->msr |= MSR_SE;
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
972cdd3904dcc56d9d24ef86be897e421d3cc364226Josh Boyer#endif
9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void bootcmds(void)
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd;
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = inchar();
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd == 'r')
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ppc_md.restart(NULL);
9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (cmd == 'h')
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ppc_md.halt();
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (cmd == 'p')
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ppc_md.power_off();
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int cpu_cmd(void)
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
990fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras	unsigned long cpu, first_cpu, last_cpu;
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int timeout;
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!scanhex(&cpu)) {
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* print cpus waiting or in xmon */
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("cpus stopped:");
996fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras		last_cpu = first_cpu = NR_CPUS;
997bc1d7702910c7c7e88eb60b58429dbfe293683ceAnton Blanchard		for_each_possible_cpu(cpu) {
998104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro			if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
999fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras				if (cpu == last_cpu + 1) {
1000fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras					last_cpu = cpu;
1001fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras				} else {
1002fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras					if (last_cpu != first_cpu)
1003736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman						printf("-0x%lx", last_cpu);
1004fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras					last_cpu = first_cpu = cpu;
1005736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman					printf(" 0x%lx", cpu);
1006fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras				}
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1009fd3bb91287b600d8b389c159e8dd96391410087bPaul Mackerras		if (last_cpu != first_cpu)
1010736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman			printf("-0x%lx", last_cpu);
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("\n");
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* try to switch to cpu specified */
1015104699c0ab473535793b5fea156adaf309afd29bKOSAKI Motohiro	if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("cpu 0x%x isn't in xmon\n", cpu);
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_taken = 0;
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mb();
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_owner = cpu;
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	timeout = 10000000;
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (!xmon_taken) {
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (--timeout == 0) {
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (test_and_set_bit(0, &xmon_taken))
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* take control back */
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mb();
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_owner = smp_processor_id();
1030736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman			printf("cpu 0x%x didn't take control\n", cpu);
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		barrier();
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */
10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned short fcstab[256] = {
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FCS(fcs, c)	(((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscsum(void)
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int i;
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned short fcs;
10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char v;
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!scanhex(&adrs))
10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!scanhex(&ncsum))
10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fcs = 0xffff;
10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < ncsum; ++i) {
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mread(adrs+i, &v, 1) == 0) {
1092736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman			printf("csum stopped at "REG"\n", adrs+i);
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fcs = FCS(fcs, v);
10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("%x\n", fcs);
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Check if this is a suitable place to put a breakpoint.
11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long check_bp_loc(unsigned long addr)
11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int instr;
11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	addr &= ~3;
110851fae6de24da57bc6cdaa1b253595c3513ecbf2dMichael Ellerman	if (!is_kernel_addr(addr)) {
11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("Breakpoints may only be placed at kernel addresses\n");
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mread(addr, &instr, sizeof(instr))) {
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("Can't read instruction at address %lx\n", addr);
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IS_MTMSRD(instr) || IS_RFID(instr)) {
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("Breakpoints may not be placed on mtmsrd or rfid "
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       "instructions\n");
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1124e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *breakpoint_help_string =
11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "Breakpoint command usage:\n"
11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "b                show breakpoints\n"
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "b <addr> [cnt]   set breakpoint at given instr addr\n"
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "bc               clear all breakpoints\n"
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "bc <n/addr>      clear breakpoint number n or at addr\n"
11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "bd <addr> [cnt]  set hardware data breakpoint\n"
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "";
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbpt_cmds(void)
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd;
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long a;
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int mode, i;
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct bpt *bp;
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char badaddr[] = "Only kernel addresses are permitted "
11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"for breakpoints\n";
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = inchar();
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (cmd) {
1146f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifndef CONFIG_8xx
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'd':	/* bd - hardware data breakpoint */
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mode = 7;
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cmd = inchar();
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cmd == 'r')
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mode = 5;
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else if (cmd == 'w')
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mode = 6;
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			termch = cmd;
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dabr.address = 0;
11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dabr.enabled = 0;
11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (scanhex(&dabr.address)) {
115951fae6de24da57bc6cdaa1b253595c3513ecbf2dMichael Ellerman			if (!is_kernel_addr(dabr.address)) {
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf(badaddr);
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
11639422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling			dabr.address &= ~HW_BRK_TYPE_DABR;
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dabr.enabled = mode | BP_DABR;
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'i':	/* bi - hardware instr breakpoint */
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!cpu_has_feature(CPU_FTR_IABR)) {
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Hardware instruction breakpoint "
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "not supported on this cpu\n");
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (iabr) {
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			iabr = NULL;
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!scanhex(&a))
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!check_bp_loc(a))
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = new_breakpoint(a);
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp != NULL) {
11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->enabled |= BP_IABR | BP_IABR_TE;
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			iabr = bp;
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1188f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'c':
11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!scanhex(&a)) {
11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* clear all breakpoints */
11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (i = 0; i < NBPTS; ++i)
11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				bpts[i].enabled = 0;
11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			iabr = NULL;
11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dabr.enabled = 0;
11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("All breakpoints cleared\n");
11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a <= NBPTS && a >= 1) {
12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* assume a breakpoint number */
12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp = &bpts[a-1];	/* bp nums are 1 based */
12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* assume a breakpoint address */
12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp = at_breakpoint(a);
12079f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman			if (bp == NULL) {
1208736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman				printf("No breakpoint at %lx\n", a);
12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1213736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman		printf("Cleared breakpoint %lx (", BP_NUM(bp));
12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_print_symbol(bp->address, " ", ")\n");
12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp->enabled = 0;
12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = cmd;
1220e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman		cmd = skipbl();
12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cmd == '?') {
12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf(breakpoint_help_string);
12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = cmd;
12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!scanhex(&a)) {
12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* print all breakpoints */
12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("   type            address\n");
12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (dabr.enabled) {
1230f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras				printf("   data   "REG"  [", dabr.address);
12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (dabr.enabled & 1)
12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf("r");
12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (dabr.enabled & 2)
12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf("w");
12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("]\n");
12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!bp->enabled)
12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					continue;
12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%2x %s   ", BP_NUM(bp),
12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    (bp->enabled & BP_IABR)? "inst": "trap");
12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				xmon_print_symbol(bp->address, "  ", "\n");
12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!check_bp_loc(a))
12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bp = new_breakpoint(a);
12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (bp != NULL)
12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			bp->enabled |= BP_TRAP;
12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Very cheap human name for vector lookup. */
12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconst char *getvecname(unsigned long vec)
12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *ret;
12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (vec) {
12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x100:	ret = "(System Reset)"; break;
12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x200:	ret = "(Machine Check)"; break;
12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x300:	ret = "(Data Access)"; break;
12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x380:	ret = "(Data SLB Access)"; break;
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x400:	ret = "(Instruction Access)"; break;
12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x480:	ret = "(Instruction SLB Access)"; break;
12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x500:	ret = "(Hardware Interrupt)"; break;
12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x600:	ret = "(Alignment)"; break;
12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x700:	ret = "(Program Check)"; break;
12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x800:	ret = "(FPU Unavailable)"; break;
12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x900:	ret = "(Decrementer)"; break;
1274660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0x980:	ret = "(Hypervisor Decrementer)"; break;
1275660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0xa00:	ret = "(Doorbell)"; break;
12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0xc00:	ret = "(System Call)"; break;
12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0xd00:	ret = "(Single Step)"; break;
1278660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0xe40:	ret = "(Emulation Assist)"; break;
1279660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0xe60:	ret = "(HMI)"; break;
1280660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0xe80:	ret = "(Hypervisor Doorbell)"; break;
12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0xf00:	ret = "(Performance Monitor)"; break;
12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0xf20:	ret = "(Altivec Unavailable)"; break;
12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
1284660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0x1500:	ret = "(Denormalisation)"; break;
1285660e034ce167b0954b83fd024c8be02c2911dbc9Michael Ellerman	case 0x1700:	ret = "(Altivec Assist)"; break;
12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default: ret = "";
12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void get_function_bounds(unsigned long pc, unsigned long *startp,
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				unsigned long *endp)
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long size, offset;
12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char *name;
12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*startp = *endp = 0;
12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pc == 0)
12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
1303ffb45122766db220d0bf3d01848d575fbbcb6430Alexey Dobriyan		name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (name != NULL) {
13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*startp = pc - offset;
13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*endp = pc - offset + size;
13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	catch_memory_errors = 0;
13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1313ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt#define LRSAVE_OFFSET		(STACK_FRAME_LR_SAVE * sizeof(unsigned long))
1314ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt#define MARKER_OFFSET		(STACK_FRAME_MARKER * sizeof(unsigned long))
1315ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt
13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_show_stack(unsigned long sp, unsigned long lr,
13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    unsigned long pc)
13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13190104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman	int max_to_print = 64;
13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long ip;
13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long newsp;
13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long marker;
13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pt_regs regs;
13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13250104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman	while (max_to_print--) {
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (sp < PAGE_OFFSET) {
13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (sp != 0)
13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("SP (%lx) is in userspace\n", sp);
13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1332f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    || !mread(sp, &newsp, sizeof(unsigned long))) {
13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Couldn't read stack frame at %lx\n", sp);
13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * For the first stack frame, try to work out if
13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * LR and/or the saved LR value in the bottommost
13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * stack frame are valid.
13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((pc | lr) != 0) {
13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			unsigned long fnstart, fnend;
13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			unsigned long nextip;
13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int printip = 1;
13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			get_function_bounds(pc, &fnstart, &fnend);
13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nextip = 0;
13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (newsp > sp)
1351f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras				mread(newsp + LRSAVE_OFFSET, &nextip,
13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				      sizeof(unsigned long));
13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (lr == ip) {
13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (lr < PAGE_OFFSET
13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    || (fnstart <= lr && lr < fnend))
13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printip = 0;
13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (lr == nextip) {
13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printip = 0;
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (lr >= PAGE_OFFSET
13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   && !(fnstart <= lr && lr < fnend)) {
13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("[link register   ] ");
13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				xmon_print_symbol(lr, " ", "\n");
13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (printip) {
1365f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras				printf("["REG"] ", sp);
13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				xmon_print_symbol(ip, " ", " (unreliable)\n");
13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pc = lr = 0;
13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
1371f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf("["REG"] ", sp);
13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_print_symbol(ip, " ", "\n");
13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Look for "regshere" marker to see if this is
13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   an exception frame. */
1377f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1378ec2b36b9f23cfbbe94d89724b796b44fd57d5221Benjamin Herrenschmidt		    && marker == STACK_FRAME_REGS_MARKER) {
1379c4de38093ed9fe94fa35c3adb14afc40bf05e1daMichael Ellerman			if (mread(sp + STACK_FRAME_OVERHEAD, &regs, sizeof(regs))
13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    != sizeof(regs)) {
13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("Couldn't read registers at %lx\n",
1382c4de38093ed9fe94fa35c3adb14afc40bf05e1daMichael Ellerman				       sp + STACK_FRAME_OVERHEAD);
13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
1385e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman			printf("--- Exception: %lx %s at ", regs.trap,
13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       getvecname(TRAP(&regs)));
13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pc = regs.nip;
13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			lr = regs.link;
13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_print_symbol(pc, " ", "\n");
13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (newsp == 0)
13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sp = newsp;
13960104cd6839bd575f0aa1af4125eb865dc0391aaeMichael Ellerman	}
13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void backtrace(struct pt_regs *excp)
14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long sp;
14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (scanhex(&sp))
14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_show_stack(sp, 0, 0);
14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scannl();
14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void print_bug_trap(struct pt_regs *regs)
14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1412ebdba9af940d63e469dc8e46b4aa1fc474e8ee2dPaul Mackerras#ifdef CONFIG_BUG
141373c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge	const struct bug_entry *bug;
14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long addr;
14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (regs->msr & MSR_PR)
14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;		/* not in kernel */
14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	addr = regs->nip;	/* address of trap instruction */
14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (addr < PAGE_OFFSET)
14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bug = find_bug(regs->nip);
14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bug == NULL)
14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
142473c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge	if (is_warning_bug(bug))
14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14270a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#ifdef CONFIG_DEBUG_BUGVERBOSE
142873c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge	printf("kernel BUG at %s:%u!\n",
142973c9ceab40b1269d6195e556773167c078ac8311Jeremy Fitzhardinge	       bug->file, bug->line);
14300a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#else
14310a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell	printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
14320a7c7efccc08f00ae6fc8e1f2de0ee61f07357fdStephen Rothwell#endif
1433ebdba9af940d63e469dc8e46b4aa1fc474e8ee2dPaul Mackerras#endif /* CONFIG_BUG */
14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14369f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void excprint(struct pt_regs *fp)
14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long trap;
14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_SMP
14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("cpu 0x%x: ", smp_processor_id());
14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_SMP */
14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	trap = TRAP(fp);
14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("    pc: ");
14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_print_symbol(fp->nip, ": ", "\n");
14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("    lr: ", fp->link);
14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_print_symbol(fp->link, ": ", "\n");
14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("    sp: %lx\n", fp->gpr[1]);
14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("   msr: %lx\n", fp->msr);
14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1455ce54152f429ed5e6ad83e5e9f61825b5a795dd1eAneesh Kumar K.V	if (trap == 0x300 || trap == 0x380 || trap == 0x600 || trap == 0x200) {
14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("   dar: %lx\n", fp->dar);
14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (trap != 0x380)
14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf(" dsisr: %lx\n", fp->dsisr);
14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("  current = 0x%lx\n", current);
1462f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64
14637230c5644188cd9e3fb380cc97dde00c464a3ba7Benjamin Herrenschmidt	printf("  paca    = 0x%lx\t softe: %d\t irq_happened: 0x%02x\n",
14647230c5644188cd9e3fb380cc97dde00c464a3ba7Benjamin Herrenschmidt	       local_paca, local_paca->soft_enabled, local_paca->irq_happened);
1465f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (current) {
14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("    pid   = %ld, comm = %s\n",
14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       current->pid, current->comm);
14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (trap == 0x700)
14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		print_bug_trap(fp);
14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14759f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void prregs(struct pt_regs *fp)
14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1477f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	int n, trap;
14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long base;
14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pt_regs regs;
14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (scanhex(&base)) {
14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (setjmp(bus_error_jmp) == 0) {
14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			catch_memory_errors = 1;
14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sync();
14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			regs = *(struct pt_regs *)base;
14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sync();
14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			__delay(200);
14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			catch_memory_errors = 0;
1490f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf("*** Error reading registers from "REG"\n",
14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       base);
14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return;
14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 0;
14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fp = &regs;
14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1498f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64
14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (FULL_REGS(fp)) {
15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (n = 0; n < 16; ++n)
1501f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       n, fp->gpr[n], n+16, fp->gpr[n+16]);
15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (n = 0; n < 7; ++n)
1505f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf("R%.2ld = "REG"   R%.2ld = "REG"\n",
15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       n, fp->gpr[n], n+7, fp->gpr[n+7]);
15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1508f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else
1509f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	for (n = 0; n < 32; ++n) {
1510f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("R%.2d = %.8x%s", n, fp->gpr[n],
1511f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		       (n & 3) == 3? "\n": "   ");
1512f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		if (n == 12 && !FULL_REGS(fp)) {
1513f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf("\n");
1514f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			break;
1515f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		}
1516f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	}
1517f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("pc  = ");
15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_print_symbol(fp->nip, " ", "\n");
152048404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras	if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
152148404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras		printf("cfar= ");
152248404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras		xmon_print_symbol(fp->orig_gpr3, " ", "\n");
152348404f2e95ef0ffd8134d89c8abcd1a15e15f1b0Paul Mackerras	}
15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("lr  = ");
15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_print_symbol(fp->link, " ", "\n");
1526f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
1527f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf("ctr = "REG"   xer = "REG"   trap = %4lx\n",
15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       fp->ctr, fp->xer, fp->trap);
1529f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	trap = TRAP(fp);
1530f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1531f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15349f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void cacheflush(void)
15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd;
15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long nflush;
15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = inchar();
15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd != 'i')
15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = cmd;
15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&adrs);
15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (termch != '\n')
15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nflush = 1;
15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex(&nflush);
15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cmd != 'i') {
15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				cflush((void *) adrs);
15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				cinval((void *) adrs);
15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	catch_memory_errors = 0;
15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15669f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic unsigned long
15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsread_spr(int n)
15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int instrs[2];
15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long (*code)(void);
15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long ret = -1UL;
1572548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#ifdef CONFIG_PPC64
1573548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	unsigned long opd[3];
15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[0] = (unsigned long)instrs;
15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[1] = 0;
15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[2] = 0;
1578548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	code = (unsigned long (*)(void)) opd;
1579548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#else
1580548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	code = (unsigned long (*)(void)) instrs;
1581548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#endif
1582548ccebc2a79c780724529948c79de0613f96776Paul Mackerras
1583548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	/* mfspr r3,n; blr */
1584548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1585548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	instrs[1] = 0x4e800020;
15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	store_inst(instrs);
15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	store_inst(instrs+1);
15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = code();
15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = size;
15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16049f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldswrite_spr(int n, unsigned long val)
16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int instrs[2];
16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long (*code)(unsigned long);
1609548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#ifdef CONFIG_PPC64
16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long opd[3];
16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[0] = (unsigned long)instrs;
16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[1] = 0;
16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	opd[2] = 0;
1615548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	code = (unsigned long (*)(unsigned long)) opd;
1616548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#else
1617548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	code = (unsigned long (*)(unsigned long)) instrs;
1618548ccebc2a79c780724529948c79de0613f96776Paul Mackerras#endif
1619548ccebc2a79c780724529948c79de0613f96776Paul Mackerras
1620548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1621548ccebc2a79c780724529948c79de0613f96776Paul Mackerras	instrs[1] = 0x4e800020;
16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	store_inst(instrs);
16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	store_inst(instrs+1);
16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		code(val);
16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = size;
16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long regno;
16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char exc_prolog;
16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern char dec_exc;
16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16429f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void super_regs(void)
16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd;
16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long val;
16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = skipbl();
16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd == '\n') {
1649e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman		unsigned long sp, toc;
16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		asm("mr %0,1" : "=r" (sp) :);
16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		asm("mr %0,2" : "=r" (toc) :);
16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1653f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("msr  = "REG"  sprg0= "REG"\n",
1654f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		       mfmsr(), mfspr(SPRN_SPRG0));
1655f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("pvr  = "REG"  sprg1= "REG"\n",
1656e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman		       mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1657f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("dec  = "REG"  sprg2= "REG"\n",
1658f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		       mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1659f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("sp   = "REG"  sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1660f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("toc  = "REG"  dar  = "REG"\n", toc, mfspr(SPRN_DAR));
16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex(&regno);
16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (cmd) {
16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'w':
16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		val = read_spr(regno);
16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scanhex(&val);
16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		write_spr(regno, val);
16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* fall through */
16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'r':
16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("spr %lx = %lx\n", regno, read_spr(regno));
16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scannl();
16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Stuff for reading and writing memory safely
16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
16829f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmread(unsigned long adrs, void *buf, int size)
16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile int n;
16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *p, *q;
16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = 0;
16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		p = (char *)adrs;
16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		q = (char *)buf;
16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (size) {
16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 2:
1696f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u16 *)q = *(u16 *)p;
16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 4:
1699f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u32 *)q = *(u32 *)p;
17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 8:
1702f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u64 *)q = *(u64 *)p;
17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for( ; n < size; ++n) {
17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*q++ = *p++;
17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				sync();
17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = size;
17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	catch_memory_errors = 0;
17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return n;
17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17199f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmwrite(unsigned long adrs, void *buf, int size)
17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile int n;
17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *p, *q;
17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = 0;
17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		p = (char *) adrs;
17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		q = (char *) buf;
17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (size) {
17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 2:
1733f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u16 *)p = *(u16 *)q;
17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 4:
1736f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u32 *)p = *(u32 *)q;
17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 8:
1739f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			*(u64 *)p = *(u64 *)q;
17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for ( ; n < size; ++n) {
17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*p++ = *q++;
17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				sync();
17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n = size;
17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
1752736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman		printf("*** Error writing address "REG"\n", adrs + n);
17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	catch_memory_errors = 0;
17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return n;
17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int fault_type;
1759f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic int fault_except;
17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *fault_chars[] = { "--", "**", "##" };
17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1762f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasstatic int handle_fault(struct pt_regs *regs)
17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1764f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	fault_except = TRAP(regs);
17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (TRAP(regs)) {
17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x200:
17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fault_type = 0;
17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x300:
17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0x380:
17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fault_type = 1;
17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fault_type = 2;
17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	longjmp(bus_error_jmp, 1);
17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SWAP(a, b, t)	((t) = (a), (a) = (b), (b) = (t))
17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17849f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbyterev(unsigned char *val, int size)
17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int t;
17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (size) {
17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:
17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[0], val[1], t);
17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 4:
17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[0], val[3], t);
17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[1], val[2], t);
17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 8: /* is there really any use for this? */
17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[0], val[7], t);
17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[1], val[6], t);
18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[2], val[5], t);
18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SWAP(val[3], val[4], t);
18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int brev;
18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mnoread;
18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1809e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *memex_help_string =
18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "Memory examine command usage:\n"
18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "m [addr] [flags] examine/change memory\n"
18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  addr is optional.  will start where left off.\n"
18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  flags may include chars from this set:\n"
18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    b   modify by bytes (default)\n"
18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    w   modify by words (2 byte)\n"
18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    l   modify by longs (4 byte)\n"
18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    d   modify by doubleword (8 byte)\n"
18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    r   toggle reverse byte order mode\n"
18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    n   do not read memory (for i/o spaces)\n"
18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "    .   ok to read (default)\n"
18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "NOTE: flags are saved as defaults\n"
18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "";
18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1824e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellermanstatic char *memex_subcmd_help_string =
18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "Memory examine subcommands:\n"
18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  hexval   write this val to current location\n"
18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  'string' write chars from string to this location\n"
18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  '        increment address\n"
18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  ^        decrement address\n"
18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etc\n"
18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  \\        decrement addr by 0x10.  \\\\=0x100, \\\\\\=0x1000, etc\n"
18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  `        clear no-read flag\n"
18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  ;        stay at this addr\n"
18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  v        change to byte mode\n"
18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  w        change to word (2 byte) mode\n"
18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  l        change to long (4 byte) mode\n"
18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  u        change to doubleword (8 byte) mode\n"
18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  m addr   change current addr\n"
18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  n        toggle no-read flag\n"
18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  r        toggle byte reverse flag\n"
18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  < count  back up count bytes\n"
18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  > count  skip forward count bytes\n"
18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "  x        exit this mode\n"
18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    "";
18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18469f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemex(void)
18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int cmd, inc, i, nslash;
18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long n;
18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char val[16];
18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&adrs);
18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cmd = skipbl();
18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd == '?') {
18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf(memex_help_string);
18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = cmd;
18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	last_cmd = "m\n";
18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while ((cmd = skipbl()) != '\n') {
18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch( cmd ){
18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'b':	size = 1;	break;
18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'w':	size = 2;	break;
18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'l':	size = 4;	break;
18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'd':	size = 8;	break;
18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'r': 	brev = !brev;	break;
18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case 'n':	mnoread = 1;	break;
18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case '.':	mnoread = 0;	break;
18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( size <= 0 )
18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		size = 1;
18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if( size > 8 )
18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		size = 8;
18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(;;){
18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!mnoread)
18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			n = mread(adrs, val, size);
1880e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras		printf(REG"%c", adrs, brev? 'r': ' ');
18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!mnoread) {
18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (brev)
18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				byterev(val, size);
18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			putchar(' ');
18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (i = 0; i < n; ++i)
18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%.2x", val[i]);
18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (; i < size; ++i)
18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%s", fault_chars[fault_type]);
18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		putchar(' ');
18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		inc = size;
18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nslash = 0;
18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for(;;){
18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if( scanhex(&n) ){
18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				for (i = 0; i < size; ++i)
18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					val[i] = n >> (i * 8);
18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!brev)
18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					byterev(val, size);
18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mwrite(adrs, val, size);
19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				inc = size;
19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cmd = skipbl();
19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (cmd == '\n')
19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			inc = 0;
19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch (cmd) {
19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '\'':
19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				for(;;){
19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					n = inchar();
19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if( n == '\\' )
19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						n = bsesc();
19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					else if( n == '\'' )
19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						break;
19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					for (i = 0; i < size; ++i)
19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						val[i] = n >> (i * 8);
19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (!brev)
19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						byterev(val, size);
19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mwrite(adrs, val, size);
19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					adrs += size;
19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs -= size;
19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				inc = size;
19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ',':
19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs += size;
19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '.':
19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mnoread = 0;
19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ';':
19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'x':
19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case EOF:
19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				scannl();
19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return;
19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'b':
19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'v':
19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				size = 1;
19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'w':
19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				size = 2;
19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'l':
19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				size = 4;
19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'u':
19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				size = 8;
19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '^':
19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs -= size;
19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '/':
19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (nslash > 0)
19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					adrs -= 1 << nslash;
19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					nslash = 0;
19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				nslash += 4;
19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs += 1 << nslash;
19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '\\':
19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (nslash < 0)
19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					adrs += 1 << -nslash;
19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else
19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					nslash = 0;
19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				nslash -= 4;
19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs -= 1 << -nslash;
19681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'm':
19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				scanhex((void *)&adrs);
19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'n':
19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mnoread = 1;
19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case 'r':
19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				brev = !brev;
19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '<':
19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				n = size;
19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				scanhex(&n);
19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs -= n;
19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '>':
19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				n = size;
19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				scanhex(&n);
19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				adrs += n;
19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case '?':
19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf(memex_subcmd_help_string);
19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adrs += inc;
19941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
19961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19979f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbsesc(void)
19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c;
20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = inchar();
20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch( c ){
20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'n':	c = '\n';	break;
20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'r':	c = '\r';	break;
20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'b':	c = '\b';	break;
20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 't':	c = '\t';	break;
20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return c;
20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20127e5b59384eebe35bff8429243f089931ce1cdf38Olaf Heringstatic void xmon_rawdump (unsigned long adrs, long ndump)
20137e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering{
20147e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	long n, m, r, nr;
20157e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	unsigned char temp[16];
20167e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering
20177e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	for (n = ndump; n > 0;) {
20187e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		r = n < 16? n: 16;
20197e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		nr = mread(adrs, temp, r);
20207e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		adrs += nr;
20217e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		for (m = 0; m < r; ++m) {
20227e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering			if (m < nr)
20237e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering				printf("%.2x", temp[m]);
20247e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering			else
20257e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering				printf("%s", fault_chars[fault_type]);
20267e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		}
20277e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		n -= r;
20287e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		if (nr < r)
20297e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering			break;
20307e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	}
20317e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	printf("\n");
20327e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering}
20337e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering
2034ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64
2035ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_one_paca(int cpu)
2036ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{
2037ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	struct paca_struct *p;
2038ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2039ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	if (setjmp(bus_error_jmp) != 0) {
2040ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2041ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		return;
2042ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	}
2043ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2044ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	catch_memory_errors = 1;
2045ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	sync();
2046ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2047ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	p = &paca[cpu];
2048ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2049ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2050ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2051ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
2052ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
2053ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
2054ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2055ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#define DUMP(paca, name, format) \
2056ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2057ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		offsetof(struct paca_struct, name));
2058ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2059ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, lock_token, "x");
2060ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, paca_index, "x");
2061ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, kernel_toc, "lx");
2062ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, kernelbase, "lx");
2063ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, kernel_msr, "lx");
2064ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, emergency_sp, "p");
2065729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar#ifdef CONFIG_PPC_BOOK3S_64
2066729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar	DUMP(p, mc_emergency_sp, "p");
2067729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar	DUMP(p, in_mce, "x");
2068729b0f715371ce1e7636b4958fc45d6882442456Mahesh Salgaonkar#endif
2069ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, data_offset, "lx");
2070ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, hw_cpu_id, "x");
2071ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, cpu_start, "x");
2072ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, kexec_state, "x");
2073ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, __current, "p");
2074ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, kstack, "lx");
2075ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, stab_rr, "lx");
2076ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, saved_r1, "lx");
2077ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, trap_save, "x");
2078ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, soft_enabled, "x");
2079ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, irq_happened, "x");
2080ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, io_sync, "x");
2081ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, irq_work_pending, "x");
2082ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	DUMP(p, nap_state_lost, "x");
2083ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2084ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#undef DUMP
2085ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2086ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	catch_memory_errors = 0;
2087ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	sync();
2088ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman}
2089ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2090ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_all_pacas(void)
2091ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{
2092ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	int cpu;
2093ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2094ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	if (num_possible_cpus() == 0) {
2095ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2096ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		return;
2097ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	}
2098ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2099ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	for_each_possible_cpu(cpu)
2100ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		dump_one_paca(cpu);
2101ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman}
2102ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2103ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellermanstatic void dump_pacas(void)
2104ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman{
2105ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	unsigned long num;
2106ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	int c;
2107ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2108ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	c = inchar();
2109ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	if (c == 'a') {
2110ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		dump_all_pacas();
2111ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		return;
2112ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	}
2113ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2114ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	termch = c;	/* Put c back, it wasn't 'a' */
2115ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2116ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	if (scanhex(&num))
2117ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		dump_one_paca(num);
2118ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	else
2119ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		dump_one_paca(xmon_owner);
2120ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman}
2121ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif
2122ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('a' <= (c) && (c) <= 'f') \
21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 || ('A' <= (c) && (c) <= 'F'))
21269f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdump(void)
21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c;
21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = inchar();
2132ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
2133ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#ifdef CONFIG_PPC64
2134ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	if (c == 'p') {
2135ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		dump_pacas();
2136ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman		return;
2137ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman	}
2138ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman#endif
2139ddadb6b8e88979a00ac44fba9c92896eec113bd1Michael Ellerman
21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = c;
21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&adrs);
21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (termch != '\n')
21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (c == 'i') {
21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scanhex(&nidump);
21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (nidump == 0)
21481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nidump = 16;
21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else if (nidump > MAX_DUMP)
21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			nidump = MAX_DUMP;
21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adrs += ppc_inst_dump(adrs, nidump, 1);
21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		last_cmd = "di\n";
2153f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar	} else if (c == 'l') {
2154f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar		dump_log_buf();
21557e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering	} else if (c == 'r') {
21567e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		scanhex(&ndump);
21577e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		if (ndump == 0)
21587e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering			ndump = 64;
21597e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		xmon_rawdump(adrs, ndump);
21607e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		adrs += ndump;
21617e5b59384eebe35bff8429243f089931ce1cdf38Olaf Hering		last_cmd = "dr\n";
21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scanhex(&ndump);
21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ndump == 0)
21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ndump = 64;
21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else if (ndump > MAX_DUMP)
21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ndump = MAX_DUMP;
21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		prdump(adrs, ndump);
21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adrs += ndump;
21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		last_cmd = "d\n";
21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21749f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsprdump(unsigned long adrs, long ndump)
21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long n, m, c, r, nr;
21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char temp[16];
21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (n = ndump; n > 0;) {
2181f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf(REG, adrs);
21821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		putchar(' ');
21831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		r = n < 16? n: 16;
21841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nr = mread(adrs, temp, r);
21851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adrs += nr;
21861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (m = 0; m < r; ++m) {
2187e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman			if ((m & (sizeof(long) - 1)) == 0 && m > 0)
2188e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras				putchar(' ');
21891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (m < nr)
21901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%.2x", temp[m]);
21911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
21921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%s", fault_chars[fault_type]);
21931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2194e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras		for (; m < 16; ++m) {
2195e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman			if ((m & (sizeof(long) - 1)) == 0)
2196e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras				putchar(' ');
21971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("  ");
2198e1449ed956ae29129bde3e5137dde1d579d585ffPaul Mackerras		}
21991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("  |");
22001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (m = 0; m < r; ++m) {
22011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (m < nr) {
22021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				c = temp[m];
22031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				putchar(' ' <= c && c <= '~'? c: '.');
22041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else
22051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				putchar(' ');
22061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
22071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		n -= r;
22081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (; m < 16; ++m)
22091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			putchar(' ');
22101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("|\n");
22111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (nr < r)
22121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
22131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
22141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
22151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22164c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermantypedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
22174c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman
22189f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
22194c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermangeneric_inst_dump(unsigned long adr, long count, int praddr,
22204c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman			instruction_dump_func dump_func)
22211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
22221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int nr, dotted;
22231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long first_adr;
22241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long inst, last_inst = 0;
22251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char val[4];
22261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dotted = 0;
22281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (first_adr = adr; count > 0; --count, adr += 4) {
22291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		nr = mread(adr, val, 4);
22301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (nr == 0) {
22311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (praddr) {
22321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				const char *x = fault_chars[fault_type];
2233f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras				printf(REG"  %s%s%s%s\n", adr, x, x, x, x);
22341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
22351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
22361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
22371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		inst = GETWORD(val);
22381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (adr > first_adr && inst == last_inst) {
22391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!dotted) {
22401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf(" ...\n");
22411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				dotted = 1;
22421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
22431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
22441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
22451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dotted = 0;
22461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		last_inst = inst;
22471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (praddr)
2248f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			printf(REG"  %.8x", adr, inst);
22491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("\t");
22504c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman		dump_func(inst, adr);
22511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("\n");
22521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
22531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return adr - first_adr;
22541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
22551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22569f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
22574c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellermanppc_inst_dump(unsigned long adr, long count, int praddr)
22584c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman{
22594c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman	return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
22604c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman}
22614c4c8723684b1b2cd0dfdf5e0685f35642bde253Michael Ellerman
22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsprint_address(unsigned long addr)
22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xmon_print_symbol(addr, "\t# ", "");
22661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2268f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridharvoid
2269f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhardump_log_buf(void)
2270f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar{
2271ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	struct kmsg_dumper dumper = { .active = 1 };
2272ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	unsigned char buf[128];
2273ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	size_t len;
2274f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar
2275e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	if (setjmp(bus_error_jmp) != 0) {
2276ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman		printf("Error dumping printk buffer!\n");
2277e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman		return;
2278e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	}
2279f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar
2280e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	catch_memory_errors = 1;
2281e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	sync();
2282f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar
2283ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	kmsg_dump_rewind_nolock(&dumper);
2284ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	while (kmsg_dump_get_line_nolock(&dumper, false, buf, sizeof(buf), &len)) {
2285ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman		buf[len] = '\0';
2286ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman		printf("%s", buf);
2287ca5dd3954a62dc14c2afff1c34b3b5d8dc74f777Michael Ellerman	}
2288f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar
2289e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	sync();
2290e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	/* wait a little while to see if we get a machine check */
2291e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	__delay(200);
2292e3bc8049e524f13e09a58f5bad70b6738494277aMichael Ellerman	catch_memory_errors = 0;
2293f312deb4cd0c88196edf6dab192b7d42514398d6Vinay Sridhar}
22941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
22951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
22961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Memory operations - move, set, print differences
22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mdest;		/* destination address */
22991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long msrc;		/* source address */
23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mval;		/* byte value to set memory to */
23011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mcount;		/* # bytes to affect */
23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mdiffs;		/* max # differences to print */
23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23049f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
23051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemops(int cmd)
23061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&mdest);
23081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( termch != '\n' )
23091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
23101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)(cmd == 's'? &mval: &msrc));
23111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( termch != '\n' )
23121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
23131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&mcount);
23141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch( cmd ){
23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'm':
23161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memmove((void *)mdest, (void *)msrc, mcount);
23171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 's':
23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset((void *)mdest, mval, mcount);
23201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'd':
23221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( termch != '\n' )
23231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			termch = 0;
23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scanhex((void *)&mdiffs);
23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23309f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
23311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned n, prt;
23341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	prt = 0;
23361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for( n = nb; n > 0; --n )
23371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( *p1++ != *p2++ )
23381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if( ++prt <= maxpr )
23391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
23401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					p1[-1], p2 - 1, p2[-1]);
23411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( prt > maxpr )
23421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("Total of %d differences\n", prt);
23431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
23441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned mend;
23461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned mask;
23471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23489f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
23491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemlocate(void)
23501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned a, n;
23521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char val[4];
23531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	last_cmd = "ml";
23551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex((void *)&mdest);
23561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (termch != '\n') {
23571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
23581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		scanhex((void *)&mend);
23591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (termch != '\n') {
23601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			termch = 0;
23611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			scanhex((void *)&mval);
23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mask = ~0;
23631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (termch != '\n') termch = 0;
23641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			scanhex((void *)&mask);
23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	n = 0;
23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (a = mdest; a < mend; a += 4) {
23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (mread(a, val, 4) == 4
23701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			&& ((GETWORD(val) ^ mval) & mask) == 0) {
23711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("%.16x:  %.16x\n", a, GETWORD(val));
23721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (++n >= 10)
23731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
23741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
23751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
23761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
23771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mskip = 0x1000;
23791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long mlim = 0xffffffff;
23801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23819f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
23821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmemzcan(void)
23831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
23841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char v;
23851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned a;
23861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ok, ook;
23871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex(&mdest);
23891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (termch != '\n') termch = 0;
23901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex(&mskip);
23911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (termch != '\n') termch = 0;
23921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scanhex(&mlim);
23931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ook = 0;
23941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (a = mdest; a < mlim; a += mskip) {
23951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ok = mread(a, &v, 1);
23961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ok && !ook) {
23971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("%.8x .. ", a);
23981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if (!ok && ook)
23991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("%.8x\n", a - mskip);
24001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ook = ok;
24011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a + mskip < a)
24021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
24031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
24041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ook)
24051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("%.8x\n", a - mskip);
24061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
24071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24089f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void proccall(void)
2409f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
2410f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	unsigned long args[8];
2411f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	unsigned long ret;
2412f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	int i;
2413f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2414f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			unsigned long, unsigned long, unsigned long,
2415f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			unsigned long, unsigned long, unsigned long);
2416f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	callfunc_t func;
2417f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
2418f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	if (!scanhex(&adrs))
2419f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		return;
2420f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	if (termch != '\n')
2421f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		termch = 0;
2422f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	for (i = 0; i < 8; ++i)
2423f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		args[i] = 0;
2424f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	for (i = 0; i < 8; ++i) {
2425f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		if (!scanhex(&args[i]) || termch == '\n')
2426f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			break;
2427f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		termch = 0;
2428f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	}
2429f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	func = (callfunc_t) adrs;
2430f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	ret = 0;
2431f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	if (setjmp(bus_error_jmp) == 0) {
2432f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		catch_memory_errors = 1;
2433f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		sync();
2434f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		ret = func(args[0], args[1], args[2], args[3],
2435f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras			   args[4], args[5], args[6], args[7]);
2436f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		sync();
2437736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman		printf("return value is 0x%lx\n", ret);
2438f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	} else {
2439f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf("*** %x exception occurred\n", fault_except);
2440f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	}
2441f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	catch_memory_errors = 0;
2442f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
2443f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
24441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Input scanning routines */
24451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint
24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsskipbl(void)
24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c;
24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( termch != 0 ){
24511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = termch;
24521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
24531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else
24541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
24551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while( c == ' ' || c == '\t' )
24561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
24571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return c;
24581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define N_PTREGS	44
24611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *regnames[N_PTREGS] = {
24621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
24631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
24641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
24651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2466f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2467f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC64
2468f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	"softe",
2469f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#else
2470f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	"mq",
2471f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
24721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"trap", "dar", "dsisr", "res"
24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
24741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint
24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsscanhex(unsigned long *vp)
24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c, d;
24791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long v;
24801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = skipbl();
24821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (c == '%') {
24831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* parse register name */
24841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		char regname[8];
24851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
24861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
24871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < sizeof(regname) - 1; ++i) {
24881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			c = inchar();
24891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!isalnum(c)) {
24901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				termch = c;
24911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
24921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
24931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			regname[i] = c;
24941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
24951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		regname[i] = 0;
24961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < N_PTREGS; ++i) {
24971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (strcmp(regnames[i], regname) == 0) {
24981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (xmon_regs == NULL) {
24991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					printf("regs not available\n");
25001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					return 0;
25011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
25021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*vp = ((unsigned long *)xmon_regs)[i];
25031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 1;
25041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
25051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("invalid register name '%%%s'\n", regname);
25071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
25081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
25091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* skip leading "0x" if any */
25111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (c == '0') {
25131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
25141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (c == 'x') {
25151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			c = inchar();
25161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
25171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			d = hexdigit(c);
25181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (d == EOF) {
25191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				termch = c;
25201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*vp = 0;
25211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return 1;
25221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
25231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else if (c == '$') {
25251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int i;
25261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i=0; i<63; i++) {
25271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			c = inchar();
25281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (isspace(c)) {
25291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				termch = c;
25301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
25311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
25321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmpstr[i] = c;
25331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tmpstr[i++] = 0;
25356879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt		*vp = 0;
25366879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt		if (setjmp(bus_error_jmp) == 0) {
25376879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt			catch_memory_errors = 1;
25386879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt			sync();
25396879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt			*vp = kallsyms_lookup_name(tmpstr);
25406879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt			sync();
25416879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt		}
25426879dc137ea4efad65cab8bf8a7c0b742bcf92ccBenjamin Herrenschmidt		catch_memory_errors = 0;
25431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(*vp)) {
25441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("unknown symbol '%s'\n", tmpstr);
25451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
25461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
25481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
25491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	d = hexdigit(c);
25511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (d == EOF) {
25521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = c;
25531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
25541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
25551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	v = 0;
25561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
25571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		v = (v << 4) + d;
25581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
25591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		d = hexdigit(c);
25601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (d != EOF);
25611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	termch = c;
25621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*vp = v;
25631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
25641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
25651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25669f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
25671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsscannl(void)
25681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
25691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c;
25701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = termch;
25721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	termch = 0;
25731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while( c != '\n' )
25741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
25751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
25761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25779f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int hexdigit(int c)
25781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
25791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( '0' <= c && c <= '9' )
25801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return c - '0';
25811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( 'A' <= c && c <= 'F' )
25821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return c - ('A' - 10);
25831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( 'a' <= c && c <= 'f' )
25841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return c - ('a' - 10);
25851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return EOF;
25861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
25871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
25891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsgetstring(char *s, int size)
25901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
25911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int c;
25921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = skipbl();
25941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
25951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( size > 1 ){
25961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*s++ = c;
25971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			--size;
25981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
25991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		c = inchar();
26001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while( c != ' ' && c != '\t' && c != '\n' );
26011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	termch = c;
26021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*s = 0;
26031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char line[256];
26061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *lineptr;
26071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26089f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
26091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsflush_input(void)
26101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lineptr = NULL;
26121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26149f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic int
26151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinchar(void)
26161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (lineptr == NULL || *lineptr == 0) {
2618fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras		if (xmon_gets(line, sizeof(line)) == NULL) {
26191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			lineptr = NULL;
26201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return EOF;
26211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
26221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		lineptr = line;
26231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
26241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return *lineptr++;
26251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26279f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void
26281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstake_input(char *str)
26291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lineptr = str;
26311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
26351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssymbol_lookup(void)
26361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int type = inchar();
26381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long addr;
26391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	static char tmp[64];
26401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (type) {
26421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 'a':
26431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (scanhex(&addr))
26441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xmon_print_symbol(addr, ": ", "\n");
26451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
26461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
26471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 's':
26481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		getstring(tmp, 64);
26491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (setjmp(bus_error_jmp) == 0) {
26501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			catch_memory_errors = 1;
26511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sync();
26521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			addr = kallsyms_lookup_name(tmp);
26531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (addr)
26541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("%s: %lx\n", tmp, addr);
26551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
26561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				printf("Symbol '%s' not found.\n", tmp);
26571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			sync();
26581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
26591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 0;
26601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		termch = 0;
26611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
26621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
26631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Print an address in numeric and symbolic form (if possible) */
26671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void xmon_print_symbol(unsigned long address, const char *mid,
26681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			      const char *after)
26691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *modname;
26711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char *name = NULL;
26721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long offset, size;
26731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2674f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf(REG, address);
26751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (setjmp(bus_error_jmp) == 0) {
26761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		catch_memory_errors = 1;
26771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
26781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		name = kallsyms_lookup(address, &size, &offset, &modname,
26791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				       tmpstr);
26801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sync();
26811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait a little while to see if we get a machine check */
26821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__delay(200);
26831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
26841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	catch_memory_errors = 0;
26861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (name) {
26881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
26891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (modname)
26901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf(" [%s]", modname);
26911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
26921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printf("%s", after);
26931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
26941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
26952d27cfd3286966c04d4192a9db5a6c7ea60eebf1Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3S_64
269613b3d13b813ab834fac67dc05f8b86dbcc29c134Michael Ellermanvoid dump_segments(void)
26971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
2699b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt	unsigned long esid,vsid,valid;
2700b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt	unsigned long llp;
27011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2702736256e4f1bc50bb8198c9b61dffd5fd0de17477Michael Ellerman	printf("SLB contents of cpu 0x%x\n", smp_processor_id());
27031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2704584f8b71a2e8abdaeb4b6f4fddaf542b61392453Michael Neuling	for (i = 0; i < mmu_slb_size; i++) {
2705b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt		asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
2706b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt		asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
2707b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt		valid = (esid & SLB_ESID_V);
2708b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt		if (valid | esid | vsid) {
2709b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt			printf("%02d %016lx %016lx", i, esid, vsid);
2710b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt			if (valid) {
2711b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt				llp = vsid & SLB_VSID_LLP;
2712b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt				if (vsid & SLB_VSID_B_1T) {
2713b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt					printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2714b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						GET_ESID_1T(esid),
2715b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2716b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						llp);
2717b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt				} else {
2718b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt					printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
2719b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						GET_ESID(esid),
2720b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						(vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2721b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt						llp);
2722b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt				}
2723b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt			} else
2724b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt				printf("\n");
2725b3b9595f50f73f0d53ebd71c463c5f09a6e64a21will schmidt		}
27261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
27271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2728f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
2729f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
2730f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#ifdef CONFIG_PPC_STD_MMU_32
2731f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerrasvoid dump_segments(void)
2732f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras{
2733f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	int i;
2734f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
2735f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf("sr0-15 =");
2736f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	for (i = 0; i < 16; ++i)
2737f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras		printf(" %x", mfsrin(i));
2738f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras	printf("\n");
2739f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras}
2740f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras#endif
2741f78541dcec327b0c46b150ee7d727f3db80275c4Paul Mackerras
27425a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#ifdef CONFIG_44x
27435a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidtstatic void dump_tlb_44x(void)
27445a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt{
27455a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt	int i;
27465a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt
27475a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt	for (i = 0; i < PPC44x_TLB_SIZE; i++) {
27485a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		unsigned long w0,w1,w2;
27495a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
27505a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
27515a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
27525a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
27535a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		if (w0 & PPC44x_TLB_VALID) {
27545a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			printf("V %08x -> %01x%08x %c%c%c%c%c",
27555a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       w0 & PPC44x_TLB_EPN_MASK,
27565a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       w1 & PPC44x_TLB_ERPN_MASK,
27575a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       w1 & PPC44x_TLB_RPN_MASK,
27585a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       (w2 & PPC44x_TLB_W) ? 'W' : 'w',
27595a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       (w2 & PPC44x_TLB_I) ? 'I' : 'i',
27605a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       (w2 & PPC44x_TLB_M) ? 'M' : 'm',
27615a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       (w2 & PPC44x_TLB_G) ? 'G' : 'g',
27625a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt			       (w2 & PPC44x_TLB_E) ? 'E' : 'e');
27635a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		}
27645a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt		printf("\n");
27655a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt	}
27665a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt}
27675a8a1a28bb35a62561367c0a1144dbc5dcb95230Benjamin Herrenschmidt#endif /* CONFIG_44x */
27689f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellerman
276903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#ifdef CONFIG_PPC_BOOK3E
277003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidtstatic void dump_tlb_book3e(void)
277103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt{
277203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	u32 mmucfg, pidmask, lpidmask;
277303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	u64 ramask;
277403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	int i, tlb, ntlbs, pidsz, lpidsz, rasz, lrat = 0;
277503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	int mmu_version;
277603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	static const char *pgsz_names[] = {
277703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  1K",
277803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  2K",
277903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  4K",
278003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  8K",
278103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 16K",
278203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 32K",
278303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 64K",
278403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"128K",
278503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"256K",
278603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"512K",
278703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  1M",
278803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  2M",
278903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  4M",
279003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  8M",
279103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 16M",
279203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 32M",
279303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 64M",
279403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"128M",
279503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"256M",
279603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"512M",
279703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  1G",
279803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  2G",
279903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  4G",
280003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  8G",
280103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 16G",
280203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 32G",
280303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		" 64G",
280403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"128G",
280503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"256G",
280603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"512G",
280703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  1T",
280803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		"  2T",
280903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	};
281003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt
281103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	/* Gather some infos about the MMU */
281203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	mmucfg = mfspr(SPRN_MMUCFG);
281303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	mmu_version = (mmucfg & 3) + 1;
281403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	ntlbs = ((mmucfg >> 2) & 3) + 1;
281503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	pidsz = ((mmucfg >> 6) & 0x1f) + 1;
281603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	lpidsz = (mmucfg >> 24) & 0xf;
281703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	rasz = (mmucfg >> 16) & 0x7f;
281803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	if ((mmu_version > 1) && (mmucfg & 0x10000))
281903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		lrat = 1;
282003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	printf("Book3E MMU MAV=%d.0,%d TLBs,%d-bit PID,%d-bit LPID,%d-bit RA\n",
282103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	       mmu_version, ntlbs, pidsz, lpidsz, rasz);
282203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	pidmask = (1ul << pidsz) - 1;
282303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	lpidmask = (1ul << lpidsz) - 1;
282403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	ramask = (1ull << rasz) - 1;
282503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt
282603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	for (tlb = 0; tlb < ntlbs; tlb++) {
282703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		u32 tlbcfg;
282803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		int nent, assoc, new_cc = 1;
282903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		printf("TLB %d:\n------\n", tlb);
283003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		switch(tlb) {
283103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		case 0:
283203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			tlbcfg = mfspr(SPRN_TLB0CFG);
283303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			break;
283403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		case 1:
283503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			tlbcfg = mfspr(SPRN_TLB1CFG);
283603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			break;
283703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		case 2:
283803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			tlbcfg = mfspr(SPRN_TLB2CFG);
283903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			break;
284003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		case 3:
284103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			tlbcfg = mfspr(SPRN_TLB3CFG);
284203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			break;
284303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		default:
284403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			printf("Unsupported TLB number !\n");
284503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			continue;
284603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		}
284703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		nent = tlbcfg & 0xfff;
284803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		assoc = (tlbcfg >> 24) & 0xff;
284903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		for (i = 0; i < nent; i++) {
285003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			u32 mas0 = MAS0_TLBSEL(tlb);
285103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			u32 mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K);
285203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			u64 mas2 = 0;
285303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			u64 mas7_mas3;
285403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			int esel = i, cc = i;
285503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt
285603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			if (assoc != 0) {
285703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				cc = i / assoc;
285803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				esel = i % assoc;
285903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				mas2 = cc * 0x1000;
286003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			}
286103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt
286203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mas0 |= MAS0_ESEL(esel);
286303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mtspr(SPRN_MAS0, mas0);
286403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mtspr(SPRN_MAS1, mas1);
286503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mtspr(SPRN_MAS2, mas2);
286603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			asm volatile("tlbre  0,0,0" : : : "memory");
286703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mas1 = mfspr(SPRN_MAS1);
286803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mas2 = mfspr(SPRN_MAS2);
286903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			mas7_mas3 = mfspr(SPRN_MAS7_MAS3);
287003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			if (assoc && (i % assoc) == 0)
287103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				new_cc = 1;
287203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			if (!(mas1 & MAS1_VALID))
287303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				continue;
287403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			if (assoc == 0)
287503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				printf("%04x- ", i);
287603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			else if (new_cc)
287703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				printf("%04x-%c", cc, 'A' + esel);
287803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			else
287903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				printf("    |%c", 'A' + esel);
288003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			new_cc = 0;
288103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			printf(" %016llx %04x %s %c%c AS%c",
288203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & ~0x3ffull,
288303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       (mas1 >> 16) & 0x3fff,
288403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       pgsz_names[(mas1 >> 7) & 0x1f],
288503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas1 & MAS1_IND ? 'I' : ' ',
288603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas1 & MAS1_IPROT ? 'P' : ' ',
288703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas1 & MAS1_TS ? '1' : '0');
288803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			printf(" %c%c%c%c%c%c%c",
288903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_X0 ? 'a' : ' ',
289003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_X1 ? 'v' : ' ',
289103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_W  ? 'w' : ' ',
289203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_I  ? 'i' : ' ',
289303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_M  ? 'm' : ' ',
289403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_G  ? 'g' : ' ',
289503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			       mas2 & MAS2_E  ? 'e' : ' ');
289603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			printf(" %016llx", mas7_mas3 & ramask & ~0x7ffull);
289703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			if (mas1 & MAS1_IND)
289803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				printf(" %s\n",
289903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       pgsz_names[(mas7_mas3 >> 1) & 0x1f]);
290003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt			else
290103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				printf(" U%c%c%c S%c%c%c\n",
290203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_UX ? 'x' : ' ',
290303247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_UW ? 'w' : ' ',
290403247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_UR ? 'r' : ' ',
290503247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_SX ? 'x' : ' ',
290603247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_SW ? 'w' : ' ',
290703247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt				       mas7_mas3 & MAS3_SR ? 'r' : ' ');
290803247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt		}
290903247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt	}
291003247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt}
291103247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt#endif /* CONFIG_PPC_BOOK3E */
291203247157f73912c98baa918cf46b98ee5483d7f8Benjamin Herrenschmidt
29139f1067c2d98ac1c43f0c82892f5647774a6ac759Michael Ellermanstatic void xmon_init(int enable)
2914b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering{
2915b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering	if (enable) {
2916b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger = xmon;
2917b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_ipi = xmon_ipi;
2918b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_bpt = xmon_bpt;
2919b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_sstep = xmon_sstep;
2920b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_iabr_match = xmon_iabr_match;
29219422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling		__debugger_break_match = xmon_break_match;
2922b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_fault_handler = xmon_fault_handler;
2923b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering	} else {
2924b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger = NULL;
2925b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_ipi = NULL;
2926b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_bpt = NULL;
2927b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_sstep = NULL;
2928b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_iabr_match = NULL;
29299422de3e953d0e60eb95f5430a9dd803eec1c6d7Michael Neuling		__debugger_break_match = NULL;
2930b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering		__debugger_fault_handler = NULL;
2931b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2Olaf Hering	}
29321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2933fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras
2934fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#ifdef CONFIG_MAGIC_SYSRQ
29351495cc9df4e81f5a8fa9b0b8f1034b14d24b7d8cDmitry Torokhovstatic void sysrq_handle_xmon(int key)
2936fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras{
2937fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	/* ensure xmon is enabled */
2938fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	xmon_init(1);
29397d12e780e003f93433d49ce78cfedf4b4c52adc5David Howells	debugger(get_irq_regs());
2940fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras}
2941fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras
29421495cc9df4e81f5a8fa9b0b8f1034b14d24b7d8cDmitry Torokhovstatic struct sysrq_key_op sysrq_xmon_op = {
2943fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	.handler =	sysrq_handle_xmon,
294490a102e59ab9c94071fe1993134daff462d17a3fzhangwei(Jovi)	.help_msg =	"xmon(x)",
2945fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	.action_msg =	"Entering xmon",
2946fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras};
2947fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras
2948fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerrasstatic int __init setup_xmon_sysrq(void)
2949fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras{
2950fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	register_sysrq_key('x', &sysrq_xmon_op);
2951fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras	return 0;
2952fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras}
2953fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras__initcall(setup_xmon_sysrq);
2954fca5dcd4835ed09bb1a48a355344aff7a25c76e0Paul Mackerras#endif /* CONFIG_MAGIC_SYSRQ */
2955476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman
2956f5e6a280d153bff3b0cd15651d29d409f8dea698Olaf Heringstatic int __initdata xmon_early, xmon_off;
2957476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman
2958476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanstatic int __init early_parse_xmon(char *p)
2959476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman{
2960476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	if (!p || strncmp(p, "early", 5) == 0) {
2961476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		/* just "xmon" is equivalent to "xmon=early" */
2962476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_init(1);
2963476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_early = 1;
2964476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	} else if (strncmp(p, "on", 2) == 0)
2965476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_init(1);
2966476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	else if (strncmp(p, "off", 3) == 0)
2967476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_off = 1;
2968476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	else if (strncmp(p, "nobt", 4) == 0)
2969476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_no_auto_backtrace = 1;
2970476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	else
2971476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		return 1;
2972476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman
2973476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	return 0;
2974476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman}
2975476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanearly_param("xmon", early_parse_xmon);
2976476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman
2977476792839467c08ddeedd8b44a7423d415b68259Michael Ellermanvoid __init xmon_setup(void)
2978476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman{
2979476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman#ifdef CONFIG_XMON_DEFAULT
2980476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	if (!xmon_off)
2981476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		xmon_init(1);
2982476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman#endif
2983476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman	if (xmon_early)
2984476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman		debugger(NULL);
2985476792839467c08ddeedd8b44a7423d415b68259Michael Ellerman}
2986ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
2987e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#ifdef CONFIG_SPU_BASE
2988ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
2989ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstruct spu_info {
2990ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	struct spu *spu;
2991ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	u64 saved_mfc_sr1_RW;
2992ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	u32 saved_spu_runcntl_RW;
299324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	unsigned long dump_addr;
2994ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	u8 stopped_ok;
2995ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman};
2996ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
2997ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#define XMON_NUM_SPUS	16	/* Enough for current hardware */
2998ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
2999ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic struct spu_info spu_info[XMON_NUM_SPUS];
3000ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3001ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanvoid xmon_register_spus(struct list_head *list)
3002ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{
3003ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	struct spu *spu;
3004ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3005ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	list_for_each_entry(spu, list, full_list) {
3006ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (spu->number >= XMON_NUM_SPUS) {
3007ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			WARN_ON(1);
3008ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			continue;
3009ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		}
3010ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3011ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		spu_info[spu->number].spu = spu;
3012ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		spu_info[spu->number].stopped_ok = 0;
301324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		spu_info[spu->number].dump_addr = (unsigned long)
301424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman				spu_info[spu->number].spu->local_store;
3015ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	}
3016ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}
3017ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3018ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic void stop_spus(void)
3019ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{
3020ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	struct spu *spu;
3021ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	int i;
3022ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	u64 tmp;
3023ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3024ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	for (i = 0; i < XMON_NUM_SPUS; i++) {
3025ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (!spu_info[i].spu)
3026ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			continue;
3027ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3028ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (setjmp(bus_error_jmp) == 0) {
3029ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			catch_memory_errors = 1;
3030ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			sync();
3031ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3032ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu = spu_info[i].spu;
3033ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3034ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu_info[i].saved_spu_runcntl_RW =
3035ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman				in_be32(&spu->problem->spu_runcntl_RW);
3036ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3037ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			tmp = spu_mfc_sr1_get(spu);
3038ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu_info[i].saved_mfc_sr1_RW = tmp;
3039ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3040ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
3041ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu_mfc_sr1_set(spu, tmp);
3042ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3043ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			sync();
3044ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			__delay(200);
3045ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3046ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu_info[i].stopped_ok = 1;
30472a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman
30482a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman			printf("Stopped spu %.2d (was %s)\n", i,
30492a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman					spu_info[i].saved_spu_runcntl_RW ?
30502a14442bfebfea23d004fa4dfd067a94f5720ed7Michael Ellerman					"running" : "stopped");
3051ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		} else {
3052ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			catch_memory_errors = 0;
3053ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			printf("*** Error stopping spu %.2d\n", i);
3054ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		}
3055ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		catch_memory_errors = 0;
3056ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	}
3057ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}
3058ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3059ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic void restart_spus(void)
3060ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{
3061ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	struct spu *spu;
3062ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	int i;
3063ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3064ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	for (i = 0; i < XMON_NUM_SPUS; i++) {
3065ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (!spu_info[i].spu)
3066ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			continue;
3067ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3068ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (!spu_info[i].stopped_ok) {
3069ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			printf("*** Error, spu %d was not successfully stopped"
3070ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman					", not restarting\n", i);
3071ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			continue;
3072ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		}
3073ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3074ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		if (setjmp(bus_error_jmp) == 0) {
3075ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			catch_memory_errors = 1;
3076ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			sync();
3077ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3078ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu = spu_info[i].spu;
3079ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
3080ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			out_be32(&spu->problem->spu_runcntl_RW,
3081ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman					spu_info[i].saved_spu_runcntl_RW);
3082ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3083ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			sync();
3084ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			__delay(200);
3085ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3086ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			printf("Restarted spu %.2d\n", i);
3087ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		} else {
3088ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			catch_memory_errors = 0;
3089ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman			printf("*** Error restarting spu %.2d\n", i);
3090ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		}
3091ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		catch_memory_errors = 0;
3092ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	}
3093ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}
3094ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3095a898497088f46252e6750405504064e2dce53117Michael Ellerman#define DUMP_WIDTH	23
3096437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman#define DUMP_VALUE(format, field, value)				\
3097a898497088f46252e6750405504064e2dce53117Michael Ellermando {									\
3098a898497088f46252e6750405504064e2dce53117Michael Ellerman	if (setjmp(bus_error_jmp) == 0) {				\
3099a898497088f46252e6750405504064e2dce53117Michael Ellerman		catch_memory_errors = 1;				\
3100a898497088f46252e6750405504064e2dce53117Michael Ellerman		sync();							\
3101a898497088f46252e6750405504064e2dce53117Michael Ellerman		printf("  %-*s = "format"\n", DUMP_WIDTH,		\
3102437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman				#field, value);				\
3103a898497088f46252e6750405504064e2dce53117Michael Ellerman		sync();							\
3104a898497088f46252e6750405504064e2dce53117Michael Ellerman		__delay(200);						\
3105a898497088f46252e6750405504064e2dce53117Michael Ellerman	} else {							\
3106a898497088f46252e6750405504064e2dce53117Michael Ellerman		catch_memory_errors = 0;				\
3107a898497088f46252e6750405504064e2dce53117Michael Ellerman		printf("  %-*s = *** Error reading field.\n",		\
3108a898497088f46252e6750405504064e2dce53117Michael Ellerman					DUMP_WIDTH, #field);		\
3109a898497088f46252e6750405504064e2dce53117Michael Ellerman	}								\
3110a898497088f46252e6750405504064e2dce53117Michael Ellerman	catch_memory_errors = 0;					\
3111a898497088f46252e6750405504064e2dce53117Michael Ellerman} while (0)
3112a898497088f46252e6750405504064e2dce53117Michael Ellerman
3113437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman#define DUMP_FIELD(obj, format, field)	\
3114437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman	DUMP_VALUE(format, field, obj->field)
3115437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman
3116a898497088f46252e6750405504064e2dce53117Michael Ellermanstatic void dump_spu_fields(struct spu *spu)
3117a898497088f46252e6750405504064e2dce53117Michael Ellerman{
3118a898497088f46252e6750405504064e2dce53117Michael Ellerman	printf("Dumping spu fields at address %p:\n", spu);
3119a898497088f46252e6750405504064e2dce53117Michael Ellerman
3120a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%x", number);
3121a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "%s", name);
3122a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", local_store_phys);
3123a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", local_store);
3124a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", ls_size);
3125a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%x", node);
3126a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", flags);
3127a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "%d", class_0_pending);
3128f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning	DUMP_FIELD(spu, "0x%lx", class_0_dar);
3129f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning	DUMP_FIELD(spu, "0x%lx", class_1_dar);
3130f3d69e0507f84903059d456c5d19f10b2df3ac69Luke Browning	DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
3131a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", irqs[0]);
3132a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", irqs[1]);
3133a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", irqs[2]);
3134a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%x", slb_replace);
3135a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "%d", pid);
3136a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", mm);
3137a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", ctx);
3138a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", rq);
3139a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", timestamp);
3140a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%lx", problem_phys);
3141a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", problem);
3142437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman	DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
3143437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman			in_be32(&spu->problem->spu_runcntl_RW));
3144437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman	DUMP_VALUE("0x%x", problem->spu_status_R,
3145437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman			in_be32(&spu->problem->spu_status_R));
3146437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman	DUMP_VALUE("0x%x", problem->spu_npc_RW,
3147437a0706837d09d8ab071c6790da07d9d6bb3d22Michael Ellerman			in_be32(&spu->problem->spu_npc_RW));
3148a898497088f46252e6750405504064e2dce53117Michael Ellerman	DUMP_FIELD(spu, "0x%p", priv2);
3149a985239bdf017e00e985c3a31149d6ae128fdc5fMichael Ellerman	DUMP_FIELD(spu, "0x%p", pdata);
3150a898497088f46252e6750405504064e2dce53117Michael Ellerman}
3151a898497088f46252e6750405504064e2dce53117Michael Ellerman
3152af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanint
3153af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanspu_inst_dump(unsigned long adr, long count, int praddr)
3154af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman{
3155af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	return generic_inst_dump(adr, count, praddr, print_insn_spu);
3156af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman}
3157af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman
3158af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellermanstatic void dump_spu_ls(unsigned long num, int subcmd)
315924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman{
316024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	unsigned long offset, addr, ls_addr;
316124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
316224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	if (setjmp(bus_error_jmp) == 0) {
316324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		catch_memory_errors = 1;
316424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		sync();
316524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		ls_addr = (unsigned long)spu_info[num].spu->local_store;
316624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		sync();
316724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		__delay(200);
316824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	} else {
316924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		catch_memory_errors = 0;
317024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		printf("*** Error: accessing spu info for spu %d\n", num);
317124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		return;
317224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	}
317324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	catch_memory_errors = 0;
317424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
317524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	if (scanhex(&offset))
317624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		addr = ls_addr + offset;
317724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	else
317824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		addr = spu_info[num].dump_addr;
317924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
318024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	if (addr >= ls_addr + LS_SIZE) {
318124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		printf("*** Error: address outside of local store\n");
318224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		return;
318324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	}
318424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
3185af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	switch (subcmd) {
3186af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	case 'i':
3187af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		addr += spu_inst_dump(addr, 16, 1);
3188af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		last_cmd = "sdi\n";
3189af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		break;
3190af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	default:
3191af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		prdump(addr, 64);
3192af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		addr += 64;
3193af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		last_cmd = "sd\n";
3194af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		break;
3195af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	}
319624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
319724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	spu_info[num].dump_addr = addr;
319824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman}
319924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
3200ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void)
3201ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{
320224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	static unsigned long num = 0;
3203af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	int cmd, subcmd = 0;
3204ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3205ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	cmd = inchar();
3206ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	switch (cmd) {
3207ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	case 's':
3208ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		stop_spus();
3209ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		break;
3210ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	case 'r':
3211ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		restart_spus();
3212ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		break;
321324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman	case 'd':
3214af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		subcmd = inchar();
3215af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman		if (isxdigit(subcmd) || subcmd == '\n')
3216af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman			termch = subcmd;
3217af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman	case 'f':
321824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		scanhex(&num);
321924a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
3220a898497088f46252e6750405504064e2dce53117Michael Ellerman			printf("*** Error: invalid spu number\n");
322124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman			return 0;
322224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		}
322324a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
322424a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		switch (cmd) {
322524a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		case 'f':
322624a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman			dump_spu_fields(spu_info[num].spu);
322724a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman			break;
322824a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		default:
3229af89fb8041562508895c8f3ba04790d7c2f4338cMichael Ellerman			dump_spu_ls(num, subcmd);
323024a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman			break;
323124a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman		}
323224a24c85d3c35790a355138d7cd34c074cb1b3acMichael Ellerman
3233a898497088f46252e6750405504064e2dce53117Michael Ellerman		break;
3234ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	default:
3235ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman		return -1;
3236ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	}
3237ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman
3238ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	return 0;
3239ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}
3240e055595d3e5f5233374211bc6893e5d16976df99Arnd Bergmann#else /* ! CONFIG_SPU_BASE */
3241ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellermanstatic int do_spu_cmd(void)
3242ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman{
3243ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman	return -1;
3244ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman}
3245ff8a8f25976aa58bbae7883405b00dcbaf4cc823Michael Ellerman#endif
3246