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