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