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