aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/xmon/xmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/xmon/xmon.c')
-rw-r--r--arch/powerpc/xmon/xmon.c75
1 files changed, 53 insertions, 22 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 1124f1146202..ef4356b29a97 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Routines providing a simple monitor for use on the PowerMac. 2 * Routines providing a simple monitor for use on the PowerMac.
3 * 3 *
4 * Copyright (C) 1996 Paul Mackerras. 4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -18,6 +18,7 @@
18#include <linux/kallsyms.h> 18#include <linux/kallsyms.h>
19#include <linux/cpumask.h> 19#include <linux/cpumask.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/sysrq.h>
21 22
22#include <asm/ptrace.h> 23#include <asm/ptrace.h>
23#include <asm/string.h> 24#include <asm/string.h>
@@ -144,15 +145,10 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
144static const char *getvecname(unsigned long vec); 145static const char *getvecname(unsigned long vec);
145 146
146extern int print_insn_powerpc(unsigned long, unsigned long, int); 147extern int print_insn_powerpc(unsigned long, unsigned long, int);
147extern void printf(const char *fmt, ...);
148extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
149extern int xmon_putc(int c, void *f);
150extern int putchar(int ch);
151 148
152extern void xmon_enter(void); 149extern void xmon_enter(void);
153extern void xmon_leave(void); 150extern void xmon_leave(void);
154 151
155extern int xmon_read_poll(void);
156extern long setjmp(long *); 152extern long setjmp(long *);
157extern void longjmp(long *, long); 153extern void longjmp(long *, long);
158extern void xmon_save_regs(struct pt_regs *); 154extern void xmon_save_regs(struct pt_regs *);
@@ -748,7 +744,6 @@ cmds(struct pt_regs *excp)
748 printf("%x:", smp_processor_id()); 744 printf("%x:", smp_processor_id());
749#endif /* CONFIG_SMP */ 745#endif /* CONFIG_SMP */
750 printf("mon> "); 746 printf("mon> ");
751 fflush(stdout);
752 flush_input(); 747 flush_input();
753 termch = 0; 748 termch = 0;
754 cmd = skipbl(); 749 cmd = skipbl();
@@ -1472,17 +1467,23 @@ read_spr(int n)
1472{ 1467{
1473 unsigned int instrs[2]; 1468 unsigned int instrs[2];
1474 unsigned long (*code)(void); 1469 unsigned long (*code)(void);
1475 unsigned long opd[3];
1476 unsigned long ret = -1UL; 1470 unsigned long ret = -1UL;
1471#ifdef CONFIG_PPC64
1472 unsigned long opd[3];
1477 1473
1478 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1479 instrs[1] = 0x4e800020;
1480 opd[0] = (unsigned long)instrs; 1474 opd[0] = (unsigned long)instrs;
1481 opd[1] = 0; 1475 opd[1] = 0;
1482 opd[2] = 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;
1483 store_inst(instrs); 1485 store_inst(instrs);
1484 store_inst(instrs+1); 1486 store_inst(instrs+1);
1485 code = (unsigned long (*)(void)) opd;
1486 1487
1487 if (setjmp(bus_error_jmp) == 0) { 1488 if (setjmp(bus_error_jmp) == 0) {
1488 catch_memory_errors = 1; 1489 catch_memory_errors = 1;
@@ -1504,16 +1505,21 @@ write_spr(int n, unsigned long val)
1504{ 1505{
1505 unsigned int instrs[2]; 1506 unsigned int instrs[2];
1506 unsigned long (*code)(unsigned long); 1507 unsigned long (*code)(unsigned long);
1508#ifdef CONFIG_PPC64
1507 unsigned long opd[3]; 1509 unsigned long opd[3];
1508 1510
1509 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1510 instrs[1] = 0x4e800020;
1511 opd[0] = (unsigned long)instrs; 1511 opd[0] = (unsigned long)instrs;
1512 opd[1] = 0; 1512 opd[1] = 0;
1513 opd[2] = 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;
1514 store_inst(instrs); 1521 store_inst(instrs);
1515 store_inst(instrs+1); 1522 store_inst(instrs+1);
1516 code = (unsigned long (*)(unsigned long)) opd;
1517 1523
1518 if (setjmp(bus_error_jmp) == 0) { 1524 if (setjmp(bus_error_jmp) == 0) {
1519 catch_memory_errors = 1; 1525 catch_memory_errors = 1;
@@ -1797,7 +1803,7 @@ memex(void)
1797 for(;;){ 1803 for(;;){
1798 if (!mnoread) 1804 if (!mnoread)
1799 n = mread(adrs, val, size); 1805 n = mread(adrs, val, size);
1800 printf("%.16x%c", adrs, brev? 'r': ' '); 1806 printf(REG"%c", adrs, brev? 'r': ' ');
1801 if (!mnoread) { 1807 if (!mnoread) {
1802 if (brev) 1808 if (brev)
1803 byterev(val, size); 1809 byterev(val, size);
@@ -1976,17 +1982,18 @@ prdump(unsigned long adrs, long ndump)
1976 nr = mread(adrs, temp, r); 1982 nr = mread(adrs, temp, r);
1977 adrs += nr; 1983 adrs += nr;
1978 for (m = 0; m < r; ++m) { 1984 for (m = 0; m < r; ++m) {
1979 if ((m & 7) == 0 && m > 0) 1985 if ((m & (sizeof(long) - 1)) == 0 && m > 0)
1980 putchar(' '); 1986 putchar(' ');
1981 if (m < nr) 1987 if (m < nr)
1982 printf("%.2x", temp[m]); 1988 printf("%.2x", temp[m]);
1983 else 1989 else
1984 printf("%s", fault_chars[fault_type]); 1990 printf("%s", fault_chars[fault_type]);
1985 } 1991 }
1986 if (m <= 8) 1992 for (; m < 16; ++m) {
1987 printf(" "); 1993 if ((m & (sizeof(long) - 1)) == 0)
1988 for (; m < 16; ++m) 1994 putchar(' ');
1989 printf(" "); 1995 printf(" ");
1996 }
1990 printf(" |"); 1997 printf(" |");
1991 for (m = 0; m < r; ++m) { 1998 for (m = 0; m < r; ++m) {
1992 if (m < nr) { 1999 if (m < nr) {
@@ -2151,7 +2158,6 @@ memzcan(void)
2151 ok = mread(a, &v, 1); 2158 ok = mread(a, &v, 1);
2152 if (ok && !ook) { 2159 if (ok && !ook) {
2153 printf("%.8x .. ", a); 2160 printf("%.8x .. ", a);
2154 fflush(stdout);
2155 } else if (!ok && ook) 2161 } else if (!ok && ook)
2156 printf("%.8x\n", a - mskip); 2162 printf("%.8x\n", a - mskip);
2157 ook = ok; 2163 ook = ok;
@@ -2372,7 +2378,7 @@ int
2372inchar(void) 2378inchar(void)
2373{ 2379{
2374 if (lineptr == NULL || *lineptr == 0) { 2380 if (lineptr == NULL || *lineptr == 0) {
2375 if (fgets(line, sizeof(line), stdin) == NULL) { 2381 if (xmon_gets(line, sizeof(line)) == NULL) {
2376 lineptr = NULL; 2382 lineptr = NULL;
2377 return EOF; 2383 return EOF;
2378 } 2384 }
@@ -2526,4 +2532,29 @@ void xmon_init(int enable)
2526 __debugger_dabr_match = NULL; 2532 __debugger_dabr_match = NULL;
2527 __debugger_fault_handler = NULL; 2533 __debugger_fault_handler = NULL;
2528 } 2534 }
2535 xmon_map_scc();
2536}
2537
2538#ifdef CONFIG_MAGIC_SYSRQ
2539static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2540 struct tty_struct *tty)
2541{
2542 /* ensure xmon is enabled */
2543 xmon_init(1);
2544 debugger(pt_regs);
2545}
2546
2547static struct sysrq_key_op sysrq_xmon_op =
2548{
2549 .handler = sysrq_handle_xmon,
2550 .help_msg = "Xmon",
2551 .action_msg = "Entering xmon",
2552};
2553
2554static int __init setup_xmon_sysrq(void)
2555{
2556 register_sysrq_key('x', &sysrq_xmon_op);
2557 return 0;
2529} 2558}
2559__initcall(setup_xmon_sysrq);
2560#endif /* CONFIG_MAGIC_SYSRQ */