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