diff options
Diffstat (limited to 'arch/powerpc/xmon/xmon.c')
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 75 |
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, | |||
144 | static const char *getvecname(unsigned long vec); | 145 | static const char *getvecname(unsigned long vec); |
145 | 146 | ||
146 | extern int print_insn_powerpc(unsigned long, unsigned long, int); | 147 | 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 | 148 | ||
152 | extern void xmon_enter(void); | 149 | extern void xmon_enter(void); |
153 | extern void xmon_leave(void); | 150 | extern void xmon_leave(void); |
154 | 151 | ||
155 | extern int xmon_read_poll(void); | ||
156 | extern long setjmp(long *); | 152 | extern long setjmp(long *); |
157 | extern void longjmp(long *, long); | 153 | extern void longjmp(long *, long); |
158 | extern void xmon_save_regs(struct pt_regs *); | 154 | extern 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 | |||
2372 | inchar(void) | 2378 | inchar(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 | ||
2539 | static 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 | |||
2547 | static struct sysrq_key_op sysrq_xmon_op = | ||
2548 | { | ||
2549 | .handler = sysrq_handle_xmon, | ||
2550 | .help_msg = "Xmon", | ||
2551 | .action_msg = "Entering xmon", | ||
2552 | }; | ||
2553 | |||
2554 | static 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 */ | ||