diff options
author | Paul Mackerras <paulus@samba.org> | 2005-10-28 08:53:37 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-10-28 08:53:37 -0400 |
commit | f78541dcec327b0c46b150ee7d727f3db80275c4 (patch) | |
tree | 9336801742d93ffa0c84c76e2b3cdc5b50c7125b | |
parent | c032524f0ddea5fcc3a2cece0d4a61f37e5ca9cd (diff) |
powerpc: Merge xmon
The merged version follows the ppc64 version pretty closely mostly,
and in fact ARCH=ppc64 now uses the arch/powerpc/xmon version.
The main difference for ppc64 is that the 'p' command to call
show_state (which was always pretty dodgy) has been replaced by
the ppc32 'p' command, which calls a given procedure (so in fact
the old 'p' command behaviour can be achieved with 'p $show_state').
Signed-off-by: Paul Mackerras <paulus@samba.org>
24 files changed, 1291 insertions, 285 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index dedf1219761a..29cda0732703 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -131,7 +131,7 @@ core-y += arch/powerpc/kernel/ \ | |||
131 | arch/powerpc/sysdev/ \ | 131 | arch/powerpc/sysdev/ \ |
132 | arch/powerpc/platforms/ | 132 | arch/powerpc/platforms/ |
133 | core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ | 133 | core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ |
134 | #core-$(CONFIG_XMON) += arch/powerpc/xmon/ | 134 | core-$(CONFIG_XMON) += arch/powerpc/xmon/ |
135 | core-$(CONFIG_APUS) += arch/ppc/amiga/ | 135 | core-$(CONFIG_APUS) += arch/ppc/amiga/ |
136 | drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ | 136 | drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ |
137 | drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ | 137 | drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 600ea19d08b5..b102e3a2415e 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -271,6 +271,9 @@ __secondary_hold_acknowledge: | |||
271 | li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ | 271 | li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ |
272 | MTMSRD(r10); /* (except for mach check in rtas) */ \ | 272 | MTMSRD(r10); /* (except for mach check in rtas) */ \ |
273 | stw r0,GPR0(r11); \ | 273 | stw r0,GPR0(r11); \ |
274 | lis r10,0x7265; /* put exception frame marker */ \ | ||
275 | addi r10,r10,0x6773; \ | ||
276 | stw r10,8(r11); \ | ||
274 | SAVE_4GPRS(3, r11); \ | 277 | SAVE_4GPRS(3, r11); \ |
275 | SAVE_2GPRS(7, r11) | 278 | SAVE_2GPRS(7, r11) |
276 | 279 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 5f3a12bb8961..8bc540337ba0 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <asm/cputable.h> | 44 | #include <asm/cputable.h> |
45 | #include <asm/btext.h> | 45 | #include <asm/btext.h> |
46 | #include <asm/div64.h> | 46 | #include <asm/div64.h> |
47 | #include <asm/xmon.h> | ||
48 | 47 | ||
49 | #ifdef CONFIG_8xx | 48 | #ifdef CONFIG_8xx |
50 | #include <asm/commproc.h> | 49 | #include <asm/commproc.h> |
@@ -238,10 +237,6 @@ EXPORT_SYMBOL(console_drivers); | |||
238 | EXPORT_SYMBOL(cacheable_memcpy); | 237 | EXPORT_SYMBOL(cacheable_memcpy); |
239 | #endif | 238 | #endif |
240 | 239 | ||
241 | #ifdef CONFIG_XMON | ||
242 | EXPORT_SYMBOL(xmon); | ||
243 | EXPORT_SYMBOL(xmon_printf); | ||
244 | #endif | ||
245 | EXPORT_SYMBOL(__up); | 240 | EXPORT_SYMBOL(__up); |
246 | EXPORT_SYMBOL(__down); | 241 | EXPORT_SYMBOL(__down); |
247 | EXPORT_SYMBOL(__down_interruptible); | 242 | EXPORT_SYMBOL(__down_interruptible); |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 7c99e6b8c76c..9680ae99b084 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -302,8 +302,10 @@ void __init setup_arch(char **cmdline_p) | |||
302 | 302 | ||
303 | #ifdef CONFIG_XMON | 303 | #ifdef CONFIG_XMON |
304 | xmon_map_scc(); | 304 | xmon_map_scc(); |
305 | if (strstr(cmd_line, "xmon")) | 305 | if (strstr(cmd_line, "xmon")) { |
306 | xmon(NULL); | 306 | xmon_init(1); |
307 | debugger(NULL); | ||
308 | } | ||
307 | #endif /* CONFIG_XMON */ | 309 | #endif /* CONFIG_XMON */ |
308 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); | 310 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); |
309 | 311 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 950e6f0fea98..681537f8ea10 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <asm/iSeries/ItLpNaca.h> | 59 | #include <asm/iSeries/ItLpNaca.h> |
60 | #include <asm/firmware.h> | 60 | #include <asm/firmware.h> |
61 | #include <asm/systemcfg.h> | 61 | #include <asm/systemcfg.h> |
62 | #include <asm/xmon.h> | ||
62 | 63 | ||
63 | #ifdef DEBUG | 64 | #ifdef DEBUG |
64 | #define DBG(fmt...) udbg_printf(fmt) | 65 | #define DBG(fmt...) udbg_printf(fmt) |
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 0115bf96751c..e6b2be3bcec1 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile | |||
@@ -11,6 +11,8 @@ obj-$(CONFIG_PPC32) += div64.o copy_32.o checksum_32.o | |||
11 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ | 11 | obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ |
12 | memcpy_64.o usercopy_64.o mem_64.o | 12 | memcpy_64.o usercopy_64.o mem_64.o |
13 | obj-$(CONFIG_PPC_ISERIES) += e2a.o | 13 | obj-$(CONFIG_PPC_ISERIES) += e2a.o |
14 | obj-$(CONFIG_XMON) += sstep.o | ||
15 | |||
14 | ifeq ($(CONFIG_PPC64),y) | 16 | ifeq ($(CONFIG_PPC64),y) |
15 | obj-$(CONFIG_SMP) += locks.o | 17 | obj-$(CONFIG_SMP) += locks.o |
16 | obj-$(CONFIG_DEBUG_KERNEL) += sstep.o | 18 | obj-$(CONFIG_DEBUG_KERNEL) += sstep.o |
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile new file mode 100644 index 000000000000..79a784f0e7a9 --- /dev/null +++ b/arch/powerpc/xmon/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # Makefile for xmon | ||
2 | |||
3 | ifdef CONFIG_PPC64 | ||
4 | EXTRA_CFLAGS += -mno-minimal-toc | ||
5 | endif | ||
6 | |||
7 | obj-$(CONFIG_8xx) += start_8xx.o | ||
8 | obj-$(CONFIG_6xx) += start_32.o | ||
9 | obj-$(CONFIG_4xx) += start_32.o | ||
10 | obj-$(CONFIG_PPC64) += start_64.o | ||
11 | obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o | ||
diff --git a/arch/ppc64/xmon/ansidecl.h b/arch/powerpc/xmon/ansidecl.h index c9b9f0929e9e..c9b9f0929e9e 100644 --- a/arch/ppc64/xmon/ansidecl.h +++ b/arch/powerpc/xmon/ansidecl.h | |||
diff --git a/arch/ppc64/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index 84211a21c6f4..84211a21c6f4 100644 --- a/arch/ppc64/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h | |||
diff --git a/arch/ppc64/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c index ac0a9d2427e0..ac0a9d2427e0 100644 --- a/arch/ppc64/xmon/ppc-dis.c +++ b/arch/powerpc/xmon/ppc-dis.c | |||
diff --git a/arch/ppc64/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c index 5ee8fc32f824..5ee8fc32f824 100644 --- a/arch/ppc64/xmon/ppc-opc.c +++ b/arch/powerpc/xmon/ppc-opc.c | |||
diff --git a/arch/ppc64/xmon/ppc.h b/arch/powerpc/xmon/ppc.h index 342237e8dd69..342237e8dd69 100644 --- a/arch/ppc64/xmon/ppc.h +++ b/arch/powerpc/xmon/ppc.h | |||
diff --git a/arch/powerpc/xmon/setjmp.S b/arch/powerpc/xmon/setjmp.S new file mode 100644 index 000000000000..f8e40dfd2bff --- /dev/null +++ b/arch/powerpc/xmon/setjmp.S | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Paul Mackerras. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: assert(sizeof(buf) > 23 * sizeof(long)) | ||
10 | */ | ||
11 | #include <asm/processor.h> | ||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/asm-offsets.h> | ||
14 | |||
15 | _GLOBAL(xmon_setjmp) | ||
16 | mflr r0 | ||
17 | STL r0,0(r3) | ||
18 | STL r1,SZL(r3) | ||
19 | STL r2,2*SZL(r3) | ||
20 | mfcr r0 | ||
21 | STL r0,3*SZL(r3) | ||
22 | STL r13,4*SZL(r3) | ||
23 | STL r14,5*SZL(r3) | ||
24 | STL r15,6*SZL(r3) | ||
25 | STL r16,7*SZL(r3) | ||
26 | STL r17,8*SZL(r3) | ||
27 | STL r18,9*SZL(r3) | ||
28 | STL r19,10*SZL(r3) | ||
29 | STL r20,11*SZL(r3) | ||
30 | STL r21,12*SZL(r3) | ||
31 | STL r22,13*SZL(r3) | ||
32 | STL r23,14*SZL(r3) | ||
33 | STL r24,15*SZL(r3) | ||
34 | STL r25,16*SZL(r3) | ||
35 | STL r26,17*SZL(r3) | ||
36 | STL r27,18*SZL(r3) | ||
37 | STL r28,19*SZL(r3) | ||
38 | STL r29,20*SZL(r3) | ||
39 | STL r30,21*SZL(r3) | ||
40 | STL r31,22*SZL(r3) | ||
41 | li r3,0 | ||
42 | blr | ||
43 | |||
44 | _GLOBAL(xmon_longjmp) | ||
45 | CMPI r4,0 | ||
46 | bne 1f | ||
47 | li r4,1 | ||
48 | 1: LDL r13,4*SZL(r3) | ||
49 | LDL r14,5*SZL(r3) | ||
50 | LDL r15,6*SZL(r3) | ||
51 | LDL r16,7*SZL(r3) | ||
52 | LDL r17,8*SZL(r3) | ||
53 | LDL r18,9*SZL(r3) | ||
54 | LDL r19,10*SZL(r3) | ||
55 | LDL r20,11*SZL(r3) | ||
56 | LDL r21,12*SZL(r3) | ||
57 | LDL r22,13*SZL(r3) | ||
58 | LDL r23,14*SZL(r3) | ||
59 | LDL r24,15*SZL(r3) | ||
60 | LDL r25,16*SZL(r3) | ||
61 | LDL r26,17*SZL(r3) | ||
62 | LDL r27,18*SZL(r3) | ||
63 | LDL r28,19*SZL(r3) | ||
64 | LDL r29,20*SZL(r3) | ||
65 | LDL r30,21*SZL(r3) | ||
66 | LDL r31,22*SZL(r3) | ||
67 | LDL r0,3*SZL(r3) | ||
68 | mtcrf 0x38,r0 | ||
69 | LDL r0,0(r3) | ||
70 | LDL r1,SZL(r3) | ||
71 | LDL r2,2*SZL(r3) | ||
72 | mtlr r0 | ||
73 | mr r3,r4 | ||
74 | blr | ||
75 | |||
76 | /* | ||
77 | * Grab the register values as they are now. | ||
78 | * This won't do a particularily good job because we really | ||
79 | * want our caller's caller's registers, and our caller has | ||
80 | * already executed its prologue. | ||
81 | * ToDo: We could reach back into the caller's save area to do | ||
82 | * a better job of representing the caller's state (note that | ||
83 | * that will be different for 32-bit and 64-bit, because of the | ||
84 | * different ABIs, though). | ||
85 | */ | ||
86 | _GLOBAL(xmon_save_regs) | ||
87 | STL r0,0*SZL(r3) | ||
88 | STL r2,2*SZL(r3) | ||
89 | STL r3,3*SZL(r3) | ||
90 | STL r4,4*SZL(r3) | ||
91 | STL r5,5*SZL(r3) | ||
92 | STL r6,6*SZL(r3) | ||
93 | STL r7,7*SZL(r3) | ||
94 | STL r8,8*SZL(r3) | ||
95 | STL r9,9*SZL(r3) | ||
96 | STL r10,10*SZL(r3) | ||
97 | STL r11,11*SZL(r3) | ||
98 | STL r12,12*SZL(r3) | ||
99 | STL r13,13*SZL(r3) | ||
100 | STL r14,14*SZL(r3) | ||
101 | STL r15,15*SZL(r3) | ||
102 | STL r16,16*SZL(r3) | ||
103 | STL r17,17*SZL(r3) | ||
104 | STL r18,18*SZL(r3) | ||
105 | STL r19,19*SZL(r3) | ||
106 | STL r20,20*SZL(r3) | ||
107 | STL r21,21*SZL(r3) | ||
108 | STL r22,22*SZL(r3) | ||
109 | STL r23,23*SZL(r3) | ||
110 | STL r24,24*SZL(r3) | ||
111 | STL r25,25*SZL(r3) | ||
112 | STL r26,26*SZL(r3) | ||
113 | STL r27,27*SZL(r3) | ||
114 | STL r28,28*SZL(r3) | ||
115 | STL r29,29*SZL(r3) | ||
116 | STL r30,30*SZL(r3) | ||
117 | STL r31,31*SZL(r3) | ||
118 | /* go up one stack frame for SP */ | ||
119 | LDL r4,0(r1) | ||
120 | STL r4,1*SZL(r3) | ||
121 | /* get caller's LR */ | ||
122 | LDL r0,LRSAVE(r4) | ||
123 | STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) | ||
124 | STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) | ||
125 | mfmsr r0 | ||
126 | STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) | ||
127 | mfctr r0 | ||
128 | STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) | ||
129 | mfxer r0 | ||
130 | STL r0,_XER-STACK_FRAME_OVERHEAD(r3) | ||
131 | mfcr r0 | ||
132 | STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) | ||
133 | li r0,0 | ||
134 | STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) | ||
135 | blr | ||
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c new file mode 100644 index 000000000000..69b658c0f760 --- /dev/null +++ b/arch/powerpc/xmon/start_32.c | |||
@@ -0,0 +1,624 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Paul Mackerras. | ||
3 | */ | ||
4 | #include <linux/config.h> | ||
5 | #include <linux/string.h> | ||
6 | #include <asm/machdep.h> | ||
7 | #include <asm/io.h> | ||
8 | #include <asm/page.h> | ||
9 | #include <linux/adb.h> | ||
10 | #include <linux/pmu.h> | ||
11 | #include <linux/cuda.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/sysrq.h> | ||
15 | #include <linux/bitops.h> | ||
16 | #include <asm/xmon.h> | ||
17 | #include <asm/prom.h> | ||
18 | #include <asm/bootx.h> | ||
19 | #include <asm/machdep.h> | ||
20 | #include <asm/errno.h> | ||
21 | #include <asm/pmac_feature.h> | ||
22 | #include <asm/processor.h> | ||
23 | #include <asm/delay.h> | ||
24 | #include <asm/btext.h> | ||
25 | |||
26 | static volatile unsigned char __iomem *sccc, *sccd; | ||
27 | unsigned int TXRDY, RXRDY, DLAB; | ||
28 | static int xmon_expect(const char *str, unsigned int timeout); | ||
29 | |||
30 | static int use_serial; | ||
31 | static int use_screen; | ||
32 | static int via_modem; | ||
33 | static int xmon_use_sccb; | ||
34 | static struct device_node *channel_node; | ||
35 | |||
36 | #define TB_SPEED 25000000 | ||
37 | |||
38 | static inline unsigned int readtb(void) | ||
39 | { | ||
40 | unsigned int ret; | ||
41 | |||
42 | asm volatile("mftb %0" : "=r" (ret) :); | ||
43 | return ret; | ||
44 | } | ||
45 | |||
46 | void buf_access(void) | ||
47 | { | ||
48 | if (DLAB) | ||
49 | sccd[3] &= ~DLAB; /* reset DLAB */ | ||
50 | } | ||
51 | |||
52 | extern int adb_init(void); | ||
53 | |||
54 | #ifdef CONFIG_PPC_CHRP | ||
55 | /* | ||
56 | * This looks in the "ranges" property for the primary PCI host bridge | ||
57 | * to find the physical address of the start of PCI/ISA I/O space. | ||
58 | * It is basically a cut-down version of pci_process_bridge_OF_ranges. | ||
59 | */ | ||
60 | static unsigned long chrp_find_phys_io_base(void) | ||
61 | { | ||
62 | struct device_node *node; | ||
63 | unsigned int *ranges; | ||
64 | unsigned long base = CHRP_ISA_IO_BASE; | ||
65 | int rlen = 0; | ||
66 | int np; | ||
67 | |||
68 | node = find_devices("isa"); | ||
69 | if (node != NULL) { | ||
70 | node = node->parent; | ||
71 | if (node == NULL || node->type == NULL | ||
72 | || strcmp(node->type, "pci") != 0) | ||
73 | node = NULL; | ||
74 | } | ||
75 | if (node == NULL) | ||
76 | node = find_devices("pci"); | ||
77 | if (node == NULL) | ||
78 | return base; | ||
79 | |||
80 | ranges = (unsigned int *) get_property(node, "ranges", &rlen); | ||
81 | np = prom_n_addr_cells(node) + 5; | ||
82 | while ((rlen -= np * sizeof(unsigned int)) >= 0) { | ||
83 | if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { | ||
84 | /* I/O space starting at 0, grab the phys base */ | ||
85 | base = ranges[np - 3]; | ||
86 | break; | ||
87 | } | ||
88 | ranges += np; | ||
89 | } | ||
90 | return base; | ||
91 | } | ||
92 | #endif /* CONFIG_PPC_CHRP */ | ||
93 | |||
94 | #ifdef CONFIG_MAGIC_SYSRQ | ||
95 | static void sysrq_handle_xmon(int key, struct pt_regs *regs, | ||
96 | struct tty_struct *tty) | ||
97 | { | ||
98 | xmon(regs); | ||
99 | } | ||
100 | |||
101 | static struct sysrq_key_op sysrq_xmon_op = | ||
102 | { | ||
103 | .handler = sysrq_handle_xmon, | ||
104 | .help_msg = "Xmon", | ||
105 | .action_msg = "Entering xmon", | ||
106 | }; | ||
107 | #endif | ||
108 | |||
109 | void | ||
110 | xmon_map_scc(void) | ||
111 | { | ||
112 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
113 | volatile unsigned char __iomem *base; | ||
114 | |||
115 | if (_machine == _MACH_Pmac) { | ||
116 | struct device_node *np; | ||
117 | unsigned long addr; | ||
118 | #ifdef CONFIG_BOOTX_TEXT | ||
119 | if (!use_screen && !use_serial | ||
120 | && !machine_is_compatible("iMac")) { | ||
121 | /* see if there is a keyboard in the device tree | ||
122 | with a parent of type "adb" */ | ||
123 | for (np = find_devices("keyboard"); np; np = np->next) | ||
124 | if (np->parent && np->parent->type | ||
125 | && strcmp(np->parent->type, "adb") == 0) | ||
126 | break; | ||
127 | |||
128 | /* needs to be hacked if xmon_printk is to be used | ||
129 | from within find_via_pmu() */ | ||
130 | #ifdef CONFIG_ADB_PMU | ||
131 | if (np != NULL && boot_text_mapped && find_via_pmu()) | ||
132 | use_screen = 1; | ||
133 | #endif | ||
134 | #ifdef CONFIG_ADB_CUDA | ||
135 | if (np != NULL && boot_text_mapped && find_via_cuda()) | ||
136 | use_screen = 1; | ||
137 | #endif | ||
138 | } | ||
139 | if (!use_screen && (np = find_devices("escc")) != NULL) { | ||
140 | /* | ||
141 | * look for the device node for the serial port | ||
142 | * we're using and see if it says it has a modem | ||
143 | */ | ||
144 | char *name = xmon_use_sccb? "ch-b": "ch-a"; | ||
145 | char *slots; | ||
146 | int l; | ||
147 | |||
148 | np = np->child; | ||
149 | while (np != NULL && strcmp(np->name, name) != 0) | ||
150 | np = np->sibling; | ||
151 | if (np != NULL) { | ||
152 | /* XXX should parse this properly */ | ||
153 | channel_node = np; | ||
154 | slots = get_property(np, "slot-names", &l); | ||
155 | if (slots != NULL && l >= 10 | ||
156 | && strcmp(slots+4, "Modem") == 0) | ||
157 | via_modem = 1; | ||
158 | } | ||
159 | } | ||
160 | btext_drawstring("xmon uses "); | ||
161 | if (use_screen) | ||
162 | btext_drawstring("screen and keyboard\n"); | ||
163 | else { | ||
164 | if (via_modem) | ||
165 | btext_drawstring("modem on "); | ||
166 | btext_drawstring(xmon_use_sccb? "printer": "modem"); | ||
167 | btext_drawstring(" port\n"); | ||
168 | } | ||
169 | |||
170 | #endif /* CONFIG_BOOTX_TEXT */ | ||
171 | |||
172 | #ifdef CHRP_ESCC | ||
173 | addr = 0xc1013020; | ||
174 | #else | ||
175 | addr = 0xf3013020; | ||
176 | #endif | ||
177 | TXRDY = 4; | ||
178 | RXRDY = 1; | ||
179 | |||
180 | np = find_devices("mac-io"); | ||
181 | if (np && np->n_addrs) | ||
182 | addr = np->addrs[0].address + 0x13020; | ||
183 | base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); | ||
184 | sccc = base + (addr & ~PAGE_MASK); | ||
185 | sccd = sccc + 0x10; | ||
186 | |||
187 | } else { | ||
188 | base = (volatile unsigned char *) isa_io_base; | ||
189 | |||
190 | #ifdef CONFIG_PPC_CHRP | ||
191 | if (_machine == _MACH_chrp) | ||
192 | base = (volatile unsigned char __iomem *) | ||
193 | ioremap(chrp_find_phys_io_base(), 0x1000); | ||
194 | #endif | ||
195 | |||
196 | sccc = base + 0x3fd; | ||
197 | sccd = base + 0x3f8; | ||
198 | if (xmon_use_sccb) { | ||
199 | sccc -= 0x100; | ||
200 | sccd -= 0x100; | ||
201 | } | ||
202 | TXRDY = 0x20; | ||
203 | RXRDY = 1; | ||
204 | DLAB = 0x80; | ||
205 | } | ||
206 | #elif defined(CONFIG_GEMINI) | ||
207 | /* should already be mapped by the kernel boot */ | ||
208 | sccc = (volatile unsigned char __iomem *) 0xffeffb0d; | ||
209 | sccd = (volatile unsigned char __iomem *) 0xffeffb08; | ||
210 | TXRDY = 0x20; | ||
211 | RXRDY = 1; | ||
212 | DLAB = 0x80; | ||
213 | #elif defined(CONFIG_405GP) | ||
214 | sccc = (volatile unsigned char __iomem *)0xef600305; | ||
215 | sccd = (volatile unsigned char __iomem *)0xef600300; | ||
216 | TXRDY = 0x20; | ||
217 | RXRDY = 1; | ||
218 | DLAB = 0x80; | ||
219 | #endif /* platform */ | ||
220 | |||
221 | register_sysrq_key('x', &sysrq_xmon_op); | ||
222 | } | ||
223 | |||
224 | static int scc_initialized = 0; | ||
225 | |||
226 | void xmon_init_scc(void); | ||
227 | extern void cuda_poll(void); | ||
228 | |||
229 | static inline void do_poll_adb(void) | ||
230 | { | ||
231 | #ifdef CONFIG_ADB_PMU | ||
232 | if (sys_ctrler == SYS_CTRLER_PMU) | ||
233 | pmu_poll_adb(); | ||
234 | #endif /* CONFIG_ADB_PMU */ | ||
235 | #ifdef CONFIG_ADB_CUDA | ||
236 | if (sys_ctrler == SYS_CTRLER_CUDA) | ||
237 | cuda_poll(); | ||
238 | #endif /* CONFIG_ADB_CUDA */ | ||
239 | } | ||
240 | |||
241 | int | ||
242 | xmon_write(void *handle, void *ptr, int nb) | ||
243 | { | ||
244 | char *p = ptr; | ||
245 | int i, c, ct; | ||
246 | |||
247 | #ifdef CONFIG_SMP | ||
248 | static unsigned long xmon_write_lock; | ||
249 | int lock_wait = 1000000; | ||
250 | int locked; | ||
251 | |||
252 | while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) | ||
253 | if (--lock_wait == 0) | ||
254 | break; | ||
255 | #endif | ||
256 | |||
257 | #ifdef CONFIG_BOOTX_TEXT | ||
258 | if (use_screen) { | ||
259 | /* write it on the screen */ | ||
260 | for (i = 0; i < nb; ++i) | ||
261 | btext_drawchar(*p++); | ||
262 | goto out; | ||
263 | } | ||
264 | #endif | ||
265 | if (!scc_initialized) | ||
266 | xmon_init_scc(); | ||
267 | ct = 0; | ||
268 | for (i = 0; i < nb; ++i) { | ||
269 | while ((*sccc & TXRDY) == 0) | ||
270 | do_poll_adb(); | ||
271 | c = p[i]; | ||
272 | if (c == '\n' && !ct) { | ||
273 | c = '\r'; | ||
274 | ct = 1; | ||
275 | --i; | ||
276 | } else { | ||
277 | ct = 0; | ||
278 | } | ||
279 | buf_access(); | ||
280 | *sccd = c; | ||
281 | eieio(); | ||
282 | } | ||
283 | |||
284 | out: | ||
285 | #ifdef CONFIG_SMP | ||
286 | if (!locked) | ||
287 | clear_bit(0, &xmon_write_lock); | ||
288 | #endif | ||
289 | return nb; | ||
290 | } | ||
291 | |||
292 | int xmon_wants_key; | ||
293 | int xmon_adb_keycode; | ||
294 | |||
295 | #ifdef CONFIG_BOOTX_TEXT | ||
296 | static int xmon_adb_shiftstate; | ||
297 | |||
298 | static unsigned char xmon_keytab[128] = | ||
299 | "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ | ||
300 | "yt123465=97-80]o" /* 0x10 - 0x1f */ | ||
301 | "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ | ||
302 | "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ | ||
303 | "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ | ||
304 | "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ | ||
305 | |||
306 | static unsigned char xmon_shift_keytab[128] = | ||
307 | "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ | ||
308 | "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ | ||
309 | "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */ | ||
310 | "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ | ||
311 | "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ | ||
312 | "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ | ||
313 | |||
314 | static int | ||
315 | xmon_get_adb_key(void) | ||
316 | { | ||
317 | int k, t, on; | ||
318 | |||
319 | xmon_wants_key = 1; | ||
320 | for (;;) { | ||
321 | xmon_adb_keycode = -1; | ||
322 | t = 0; | ||
323 | on = 0; | ||
324 | do { | ||
325 | if (--t < 0) { | ||
326 | on = 1 - on; | ||
327 | btext_drawchar(on? 0xdb: 0x20); | ||
328 | btext_drawchar('\b'); | ||
329 | t = 200000; | ||
330 | } | ||
331 | do_poll_adb(); | ||
332 | } while (xmon_adb_keycode == -1); | ||
333 | k = xmon_adb_keycode; | ||
334 | if (on) | ||
335 | btext_drawstring(" \b"); | ||
336 | |||
337 | /* test for shift keys */ | ||
338 | if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { | ||
339 | xmon_adb_shiftstate = (k & 0x80) == 0; | ||
340 | continue; | ||
341 | } | ||
342 | if (k >= 0x80) | ||
343 | continue; /* ignore up transitions */ | ||
344 | k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; | ||
345 | if (k != 0) | ||
346 | break; | ||
347 | } | ||
348 | xmon_wants_key = 0; | ||
349 | return k; | ||
350 | } | ||
351 | #endif /* CONFIG_BOOTX_TEXT */ | ||
352 | |||
353 | int | ||
354 | xmon_read(void *handle, void *ptr, int nb) | ||
355 | { | ||
356 | char *p = ptr; | ||
357 | int i; | ||
358 | |||
359 | #ifdef CONFIG_BOOTX_TEXT | ||
360 | if (use_screen) { | ||
361 | for (i = 0; i < nb; ++i) | ||
362 | *p++ = xmon_get_adb_key(); | ||
363 | return i; | ||
364 | } | ||
365 | #endif | ||
366 | if (!scc_initialized) | ||
367 | xmon_init_scc(); | ||
368 | for (i = 0; i < nb; ++i) { | ||
369 | while ((*sccc & RXRDY) == 0) | ||
370 | do_poll_adb(); | ||
371 | buf_access(); | ||
372 | *p++ = *sccd; | ||
373 | } | ||
374 | return i; | ||
375 | } | ||
376 | |||
377 | int | ||
378 | xmon_read_poll(void) | ||
379 | { | ||
380 | if ((*sccc & RXRDY) == 0) { | ||
381 | do_poll_adb(); | ||
382 | return -1; | ||
383 | } | ||
384 | buf_access(); | ||
385 | return *sccd; | ||
386 | } | ||
387 | |||
388 | static unsigned char scc_inittab[] = { | ||
389 | 13, 0, /* set baud rate divisor */ | ||
390 | 12, 1, | ||
391 | 14, 1, /* baud rate gen enable, src=rtxc */ | ||
392 | 11, 0x50, /* clocks = br gen */ | ||
393 | 5, 0xea, /* tx 8 bits, assert DTR & RTS */ | ||
394 | 4, 0x46, /* x16 clock, 1 stop */ | ||
395 | 3, 0xc1, /* rx enable, 8 bits */ | ||
396 | }; | ||
397 | |||
398 | void | ||
399 | xmon_init_scc(void) | ||
400 | { | ||
401 | if ( _machine == _MACH_chrp ) | ||
402 | { | ||
403 | sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ | ||
404 | sccd[0] = 12; eieio(); /* DLL = 9600 baud */ | ||
405 | sccd[1] = 0; eieio(); | ||
406 | sccd[2] = 0; eieio(); /* FCR = 0 */ | ||
407 | sccd[3] = 3; eieio(); /* LCR = 8N1 */ | ||
408 | sccd[1] = 0; eieio(); /* IER = 0 */ | ||
409 | } | ||
410 | else if ( _machine == _MACH_Pmac ) | ||
411 | { | ||
412 | int i, x; | ||
413 | |||
414 | if (channel_node != 0) | ||
415 | pmac_call_feature( | ||
416 | PMAC_FTR_SCC_ENABLE, | ||
417 | channel_node, | ||
418 | PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); | ||
419 | printk(KERN_INFO "Serial port locked ON by debugger !\n"); | ||
420 | if (via_modem && channel_node != 0) { | ||
421 | unsigned int t0; | ||
422 | |||
423 | pmac_call_feature( | ||
424 | PMAC_FTR_MODEM_ENABLE, | ||
425 | channel_node, 0, 1); | ||
426 | printk(KERN_INFO "Modem powered up by debugger !\n"); | ||
427 | t0 = readtb(); | ||
428 | while (readtb() - t0 < 3*TB_SPEED) | ||
429 | eieio(); | ||
430 | } | ||
431 | /* use the B channel if requested */ | ||
432 | if (xmon_use_sccb) { | ||
433 | sccc = (volatile unsigned char *) | ||
434 | ((unsigned long)sccc & ~0x20); | ||
435 | sccd = sccc + 0x10; | ||
436 | } | ||
437 | for (i = 20000; i != 0; --i) { | ||
438 | x = *sccc; eieio(); | ||
439 | } | ||
440 | *sccc = 9; eieio(); /* reset A or B side */ | ||
441 | *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); | ||
442 | for (i = 0; i < sizeof(scc_inittab); ++i) { | ||
443 | *sccc = scc_inittab[i]; | ||
444 | eieio(); | ||
445 | } | ||
446 | } | ||
447 | scc_initialized = 1; | ||
448 | if (via_modem) { | ||
449 | for (;;) { | ||
450 | xmon_write(NULL, "ATE1V1\r", 7); | ||
451 | if (xmon_expect("OK", 5)) { | ||
452 | xmon_write(NULL, "ATA\r", 4); | ||
453 | if (xmon_expect("CONNECT", 40)) | ||
454 | break; | ||
455 | } | ||
456 | xmon_write(NULL, "+++", 3); | ||
457 | xmon_expect("OK", 3); | ||
458 | } | ||
459 | } | ||
460 | } | ||
461 | |||
462 | void *xmon_stdin; | ||
463 | void *xmon_stdout; | ||
464 | void *xmon_stderr; | ||
465 | |||
466 | int xmon_putc(int c, void *f) | ||
467 | { | ||
468 | char ch = c; | ||
469 | |||
470 | if (c == '\n') | ||
471 | xmon_putc('\r', f); | ||
472 | return xmon_write(f, &ch, 1) == 1? c: -1; | ||
473 | } | ||
474 | |||
475 | int xmon_putchar(int c) | ||
476 | { | ||
477 | return xmon_putc(c, xmon_stdout); | ||
478 | } | ||
479 | |||
480 | int xmon_fputs(char *str, void *f) | ||
481 | { | ||
482 | int n = strlen(str); | ||
483 | |||
484 | return xmon_write(f, str, n) == n? 0: -1; | ||
485 | } | ||
486 | |||
487 | int | ||
488 | xmon_readchar(void) | ||
489 | { | ||
490 | char ch; | ||
491 | |||
492 | for (;;) { | ||
493 | switch (xmon_read(xmon_stdin, &ch, 1)) { | ||
494 | case 1: | ||
495 | return ch; | ||
496 | case -1: | ||
497 | xmon_printf("read(stdin) returned -1\r\n", 0, 0); | ||
498 | return -1; | ||
499 | } | ||
500 | } | ||
501 | } | ||
502 | |||
503 | static char line[256]; | ||
504 | static char *lineptr; | ||
505 | static int lineleft; | ||
506 | |||
507 | int xmon_expect(const char *str, unsigned int timeout) | ||
508 | { | ||
509 | int c; | ||
510 | unsigned int t0; | ||
511 | |||
512 | timeout *= TB_SPEED; | ||
513 | t0 = readtb(); | ||
514 | do { | ||
515 | lineptr = line; | ||
516 | for (;;) { | ||
517 | c = xmon_read_poll(); | ||
518 | if (c == -1) { | ||
519 | if (readtb() - t0 > timeout) | ||
520 | return 0; | ||
521 | continue; | ||
522 | } | ||
523 | if (c == '\n') | ||
524 | break; | ||
525 | if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | ||
526 | *lineptr++ = c; | ||
527 | } | ||
528 | *lineptr = 0; | ||
529 | } while (strstr(line, str) == NULL); | ||
530 | return 1; | ||
531 | } | ||
532 | |||
533 | int | ||
534 | xmon_getchar(void) | ||
535 | { | ||
536 | int c; | ||
537 | |||
538 | if (lineleft == 0) { | ||
539 | lineptr = line; | ||
540 | for (;;) { | ||
541 | c = xmon_readchar(); | ||
542 | if (c == -1 || c == 4) | ||
543 | break; | ||
544 | if (c == '\r' || c == '\n') { | ||
545 | *lineptr++ = '\n'; | ||
546 | xmon_putchar('\n'); | ||
547 | break; | ||
548 | } | ||
549 | switch (c) { | ||
550 | case 0177: | ||
551 | case '\b': | ||
552 | if (lineptr > line) { | ||
553 | xmon_putchar('\b'); | ||
554 | xmon_putchar(' '); | ||
555 | xmon_putchar('\b'); | ||
556 | --lineptr; | ||
557 | } | ||
558 | break; | ||
559 | case 'U' & 0x1F: | ||
560 | while (lineptr > line) { | ||
561 | xmon_putchar('\b'); | ||
562 | xmon_putchar(' '); | ||
563 | xmon_putchar('\b'); | ||
564 | --lineptr; | ||
565 | } | ||
566 | break; | ||
567 | default: | ||
568 | if (lineptr >= &line[sizeof(line) - 1]) | ||
569 | xmon_putchar('\a'); | ||
570 | else { | ||
571 | xmon_putchar(c); | ||
572 | *lineptr++ = c; | ||
573 | } | ||
574 | } | ||
575 | } | ||
576 | lineleft = lineptr - line; | ||
577 | lineptr = line; | ||
578 | } | ||
579 | if (lineleft == 0) | ||
580 | return -1; | ||
581 | --lineleft; | ||
582 | return *lineptr++; | ||
583 | } | ||
584 | |||
585 | char * | ||
586 | xmon_fgets(char *str, int nb, void *f) | ||
587 | { | ||
588 | char *p; | ||
589 | int c; | ||
590 | |||
591 | for (p = str; p < str + nb - 1; ) { | ||
592 | c = xmon_getchar(); | ||
593 | if (c == -1) { | ||
594 | if (p == str) | ||
595 | return NULL; | ||
596 | break; | ||
597 | } | ||
598 | *p++ = c; | ||
599 | if (c == '\n') | ||
600 | break; | ||
601 | } | ||
602 | *p = 0; | ||
603 | return str; | ||
604 | } | ||
605 | |||
606 | void | ||
607 | xmon_enter(void) | ||
608 | { | ||
609 | #ifdef CONFIG_ADB_PMU | ||
610 | if (_machine == _MACH_Pmac) { | ||
611 | pmu_suspend(); | ||
612 | } | ||
613 | #endif | ||
614 | } | ||
615 | |||
616 | void | ||
617 | xmon_leave(void) | ||
618 | { | ||
619 | #ifdef CONFIG_ADB_PMU | ||
620 | if (_machine == _MACH_Pmac) { | ||
621 | pmu_resume(); | ||
622 | } | ||
623 | #endif | ||
624 | } | ||
diff --git a/arch/ppc64/xmon/start.c b/arch/powerpc/xmon/start_64.c index e50c158191e1..e50c158191e1 100644 --- a/arch/ppc64/xmon/start.c +++ b/arch/powerpc/xmon/start_64.c | |||
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c new file mode 100644 index 000000000000..a48bd594cf61 --- /dev/null +++ b/arch/powerpc/xmon/start_8xx.c | |||
@@ -0,0 +1,287 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Paul Mackerras. | ||
3 | * Copyright (C) 2000 Dan Malek. | ||
4 | * Quick hack of Paul's code to make XMON work on 8xx processors. Lots | ||
5 | * of assumptions, like the SMC1 is used, it has been initialized by the | ||
6 | * loader at some point, and we can just stuff and suck bytes. | ||
7 | * We rely upon the 8xx uart driver to support us, as the interface | ||
8 | * changes between boot up and operational phases of the kernel. | ||
9 | */ | ||
10 | #include <linux/string.h> | ||
11 | #include <asm/machdep.h> | ||
12 | #include <asm/io.h> | ||
13 | #include <asm/page.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <asm/8xx_immap.h> | ||
16 | #include <asm/mpc8xx.h> | ||
17 | #include <asm/commproc.h> | ||
18 | |||
19 | extern void xmon_printf(const char *fmt, ...); | ||
20 | extern int xmon_8xx_write(char *str, int nb); | ||
21 | extern int xmon_8xx_read_poll(void); | ||
22 | extern int xmon_8xx_read_char(void); | ||
23 | void prom_drawhex(uint); | ||
24 | void prom_drawstring(const char *str); | ||
25 | |||
26 | static int use_screen = 1; /* default */ | ||
27 | |||
28 | #define TB_SPEED 25000000 | ||
29 | |||
30 | static inline unsigned int readtb(void) | ||
31 | { | ||
32 | unsigned int ret; | ||
33 | |||
34 | asm volatile("mftb %0" : "=r" (ret) :); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | void buf_access(void) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | void | ||
43 | xmon_map_scc(void) | ||
44 | { | ||
45 | |||
46 | cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); | ||
47 | use_screen = 0; | ||
48 | |||
49 | prom_drawstring("xmon uses serial port\n"); | ||
50 | } | ||
51 | |||
52 | static int scc_initialized = 0; | ||
53 | |||
54 | void xmon_init_scc(void); | ||
55 | |||
56 | int | ||
57 | xmon_write(void *handle, void *ptr, int nb) | ||
58 | { | ||
59 | char *p = ptr; | ||
60 | int i, c, ct; | ||
61 | |||
62 | if (!scc_initialized) | ||
63 | xmon_init_scc(); | ||
64 | |||
65 | return(xmon_8xx_write(ptr, nb)); | ||
66 | } | ||
67 | |||
68 | int xmon_wants_key; | ||
69 | |||
70 | int | ||
71 | xmon_read(void *handle, void *ptr, int nb) | ||
72 | { | ||
73 | char *p = ptr; | ||
74 | int i; | ||
75 | |||
76 | if (!scc_initialized) | ||
77 | xmon_init_scc(); | ||
78 | |||
79 | for (i = 0; i < nb; ++i) { | ||
80 | *p++ = xmon_8xx_read_char(); | ||
81 | } | ||
82 | return i; | ||
83 | } | ||
84 | |||
85 | int | ||
86 | xmon_read_poll(void) | ||
87 | { | ||
88 | return(xmon_8xx_read_poll()); | ||
89 | } | ||
90 | |||
91 | void | ||
92 | xmon_init_scc() | ||
93 | { | ||
94 | scc_initialized = 1; | ||
95 | } | ||
96 | |||
97 | #if 0 | ||
98 | extern int (*prom_entry)(void *); | ||
99 | |||
100 | int | ||
101 | xmon_exit(void) | ||
102 | { | ||
103 | struct prom_args { | ||
104 | char *service; | ||
105 | } args; | ||
106 | |||
107 | for (;;) { | ||
108 | args.service = "exit"; | ||
109 | (*prom_entry)(&args); | ||
110 | } | ||
111 | } | ||
112 | #endif | ||
113 | |||
114 | void *xmon_stdin; | ||
115 | void *xmon_stdout; | ||
116 | void *xmon_stderr; | ||
117 | |||
118 | void | ||
119 | xmon_init(void) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | int | ||
124 | xmon_putc(int c, void *f) | ||
125 | { | ||
126 | char ch = c; | ||
127 | |||
128 | if (c == '\n') | ||
129 | xmon_putc('\r', f); | ||
130 | return xmon_write(f, &ch, 1) == 1? c: -1; | ||
131 | } | ||
132 | |||
133 | int | ||
134 | xmon_putchar(int c) | ||
135 | { | ||
136 | return xmon_putc(c, xmon_stdout); | ||
137 | } | ||
138 | |||
139 | int | ||
140 | xmon_fputs(char *str, void *f) | ||
141 | { | ||
142 | int n = strlen(str); | ||
143 | |||
144 | return xmon_write(f, str, n) == n? 0: -1; | ||
145 | } | ||
146 | |||
147 | int | ||
148 | xmon_readchar(void) | ||
149 | { | ||
150 | char ch; | ||
151 | |||
152 | for (;;) { | ||
153 | switch (xmon_read(xmon_stdin, &ch, 1)) { | ||
154 | case 1: | ||
155 | return ch; | ||
156 | case -1: | ||
157 | xmon_printf("read(stdin) returned -1\r\n", 0, 0); | ||
158 | return -1; | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static char line[256]; | ||
164 | static char *lineptr; | ||
165 | static int lineleft; | ||
166 | |||
167 | #if 0 | ||
168 | int xmon_expect(const char *str, unsigned int timeout) | ||
169 | { | ||
170 | int c; | ||
171 | unsigned int t0; | ||
172 | |||
173 | timeout *= TB_SPEED; | ||
174 | t0 = readtb(); | ||
175 | do { | ||
176 | lineptr = line; | ||
177 | for (;;) { | ||
178 | c = xmon_read_poll(); | ||
179 | if (c == -1) { | ||
180 | if (readtb() - t0 > timeout) | ||
181 | return 0; | ||
182 | continue; | ||
183 | } | ||
184 | if (c == '\n') | ||
185 | break; | ||
186 | if (c != '\r' && lineptr < &line[sizeof(line) - 1]) | ||
187 | *lineptr++ = c; | ||
188 | } | ||
189 | *lineptr = 0; | ||
190 | } while (strstr(line, str) == NULL); | ||
191 | return 1; | ||
192 | } | ||
193 | #endif | ||
194 | |||
195 | int | ||
196 | xmon_getchar(void) | ||
197 | { | ||
198 | int c; | ||
199 | |||
200 | if (lineleft == 0) { | ||
201 | lineptr = line; | ||
202 | for (;;) { | ||
203 | c = xmon_readchar(); | ||
204 | if (c == -1 || c == 4) | ||
205 | break; | ||
206 | if (c == '\r' || c == '\n') { | ||
207 | *lineptr++ = '\n'; | ||
208 | xmon_putchar('\n'); | ||
209 | break; | ||
210 | } | ||
211 | switch (c) { | ||
212 | case 0177: | ||
213 | case '\b': | ||
214 | if (lineptr > line) { | ||
215 | xmon_putchar('\b'); | ||
216 | xmon_putchar(' '); | ||
217 | xmon_putchar('\b'); | ||
218 | --lineptr; | ||
219 | } | ||
220 | break; | ||
221 | case 'U' & 0x1F: | ||
222 | while (lineptr > line) { | ||
223 | xmon_putchar('\b'); | ||
224 | xmon_putchar(' '); | ||
225 | xmon_putchar('\b'); | ||
226 | --lineptr; | ||
227 | } | ||
228 | break; | ||
229 | default: | ||
230 | if (lineptr >= &line[sizeof(line) - 1]) | ||
231 | xmon_putchar('\a'); | ||
232 | else { | ||
233 | xmon_putchar(c); | ||
234 | *lineptr++ = c; | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | lineleft = lineptr - line; | ||
239 | lineptr = line; | ||
240 | } | ||
241 | if (lineleft == 0) | ||
242 | return -1; | ||
243 | --lineleft; | ||
244 | return *lineptr++; | ||
245 | } | ||
246 | |||
247 | char * | ||
248 | xmon_fgets(char *str, int nb, void *f) | ||
249 | { | ||
250 | char *p; | ||
251 | int c; | ||
252 | |||
253 | for (p = str; p < str + nb - 1; ) { | ||
254 | c = xmon_getchar(); | ||
255 | if (c == -1) { | ||
256 | if (p == str) | ||
257 | return 0; | ||
258 | break; | ||
259 | } | ||
260 | *p++ = c; | ||
261 | if (c == '\n') | ||
262 | break; | ||
263 | } | ||
264 | *p = 0; | ||
265 | return str; | ||
266 | } | ||
267 | |||
268 | void | ||
269 | prom_drawhex(uint val) | ||
270 | { | ||
271 | unsigned char buf[10]; | ||
272 | |||
273 | int i; | ||
274 | for (i = 7; i >= 0; i--) | ||
275 | { | ||
276 | buf[i] = "0123456789abcdef"[val & 0x0f]; | ||
277 | val >>= 4; | ||
278 | } | ||
279 | buf[8] = '\0'; | ||
280 | xmon_fputs(buf, xmon_stdout); | ||
281 | } | ||
282 | |||
283 | void | ||
284 | prom_drawstring(const char *str) | ||
285 | { | ||
286 | xmon_fputs(str, xmon_stdout); | ||
287 | } | ||
diff --git a/arch/ppc64/xmon/subr_prf.c b/arch/powerpc/xmon/subr_prf.c index 5242bd7d0959..b48738c6dd33 100644 --- a/arch/ppc64/xmon/subr_prf.c +++ b/arch/powerpc/xmon/subr_prf.c | |||
@@ -18,13 +18,13 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/module.h> | ||
21 | #include <stdarg.h> | 22 | #include <stdarg.h> |
22 | #include "nonstdio.h" | 23 | #include "nonstdio.h" |
23 | 24 | ||
24 | extern int xmon_write(void *, void *, int); | 25 | extern int xmon_write(void *, void *, int); |
25 | 26 | ||
26 | void | 27 | void xmon_vfprintf(void *f, const char *fmt, va_list ap) |
27 | xmon_vfprintf(void *f, const char *fmt, va_list ap) | ||
28 | { | 28 | { |
29 | static char xmon_buf[2048]; | 29 | static char xmon_buf[2048]; |
30 | int n; | 30 | int n; |
@@ -33,8 +33,7 @@ xmon_vfprintf(void *f, const char *fmt, va_list ap) | |||
33 | xmon_write(f, xmon_buf, n); | 33 | xmon_write(f, xmon_buf, n); |
34 | } | 34 | } |
35 | 35 | ||
36 | void | 36 | void xmon_printf(const char *fmt, ...) |
37 | xmon_printf(const char *fmt, ...) | ||
38 | { | 37 | { |
39 | va_list ap; | 38 | va_list ap; |
40 | 39 | ||
@@ -42,9 +41,9 @@ xmon_printf(const char *fmt, ...) | |||
42 | xmon_vfprintf(stdout, fmt, ap); | 41 | xmon_vfprintf(stdout, fmt, ap); |
43 | va_end(ap); | 42 | va_end(ap); |
44 | } | 43 | } |
44 | EXPORT_SYMBOL(xmon_printf); | ||
45 | 45 | ||
46 | void | 46 | void xmon_fprintf(void *f, const char *fmt, ...) |
47 | xmon_fprintf(void *f, const char *fmt, ...) | ||
48 | { | 47 | { |
49 | va_list ap; | 48 | va_list ap; |
50 | 49 | ||
diff --git a/arch/ppc64/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 74e63a886a69..d0623e0fd8ee 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -17,25 +17,31 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
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 | 21 | ||
21 | #include <asm/ptrace.h> | 22 | #include <asm/ptrace.h> |
22 | #include <asm/string.h> | 23 | #include <asm/string.h> |
23 | #include <asm/prom.h> | 24 | #include <asm/prom.h> |
24 | #include <asm/machdep.h> | 25 | #include <asm/machdep.h> |
26 | #include <asm/xmon.h> | ||
27 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
28 | #include <asm/backlight.h> | ||
29 | #endif | ||
25 | #include <asm/processor.h> | 30 | #include <asm/processor.h> |
26 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
27 | #include <asm/mmu.h> | 32 | #include <asm/mmu.h> |
28 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
29 | #include <asm/paca.h> | ||
30 | #include <asm/ppcdebug.h> | ||
31 | #include <asm/cputable.h> | 34 | #include <asm/cputable.h> |
32 | #include <asm/rtas.h> | 35 | #include <asm/rtas.h> |
33 | #include <asm/sstep.h> | 36 | #include <asm/sstep.h> |
34 | #include <asm/bug.h> | 37 | #include <asm/bug.h> |
38 | |||
39 | #ifdef CONFIG_PPC64 | ||
35 | #include <asm/hvcall.h> | 40 | #include <asm/hvcall.h> |
41 | #include <asm/paca.h> | ||
42 | #endif | ||
36 | 43 | ||
37 | #include "nonstdio.h" | 44 | #include "nonstdio.h" |
38 | #include "privinst.h" | ||
39 | 45 | ||
40 | #define scanhex xmon_scanhex | 46 | #define scanhex xmon_scanhex |
41 | #define skipbl xmon_skipbl | 47 | #define skipbl xmon_skipbl |
@@ -58,7 +64,7 @@ static unsigned long ncsum = 4096; | |||
58 | static int termch; | 64 | static int termch; |
59 | static char tmpstr[128]; | 65 | static char tmpstr[128]; |
60 | 66 | ||
61 | #define JMP_BUF_LEN (184/sizeof(long)) | 67 | #define JMP_BUF_LEN 23 |
62 | static long bus_error_jmp[JMP_BUF_LEN]; | 68 | static long bus_error_jmp[JMP_BUF_LEN]; |
63 | static int catch_memory_errors; | 69 | static int catch_memory_errors; |
64 | static long *xmon_fault_jmp[NR_CPUS]; | 70 | static long *xmon_fault_jmp[NR_CPUS]; |
@@ -130,23 +136,36 @@ static void cacheflush(void); | |||
130 | static int cpu_cmd(void); | 136 | static int cpu_cmd(void); |
131 | static void csum(void); | 137 | static void csum(void); |
132 | static void bootcmds(void); | 138 | static void bootcmds(void); |
139 | static void proccall(void); | ||
133 | void dump_segments(void); | 140 | void dump_segments(void); |
134 | static void symbol_lookup(void); | 141 | static void symbol_lookup(void); |
135 | static void xmon_print_symbol(unsigned long address, const char *mid, | 142 | static void xmon_print_symbol(unsigned long address, const char *mid, |
136 | const char *after); | 143 | const char *after); |
137 | static const char *getvecname(unsigned long vec); | 144 | static const char *getvecname(unsigned long vec); |
138 | 145 | ||
139 | static void debug_trace(void); | ||
140 | |||
141 | extern int print_insn_powerpc(unsigned long, unsigned long, int); | 146 | extern int print_insn_powerpc(unsigned long, unsigned long, int); |
142 | extern void printf(const char *fmt, ...); | 147 | extern void printf(const char *fmt, ...); |
143 | extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); | 148 | extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); |
144 | extern int xmon_putc(int c, void *f); | 149 | extern int xmon_putc(int c, void *f); |
145 | extern int putchar(int ch); | 150 | extern int putchar(int ch); |
151 | |||
152 | extern void xmon_enter(void); | ||
153 | extern void xmon_leave(void); | ||
154 | |||
146 | extern int xmon_read_poll(void); | 155 | extern int xmon_read_poll(void); |
147 | extern int setjmp(long *); | 156 | extern long setjmp(long *); |
148 | extern void longjmp(long *, int); | 157 | extern void longjmp(long *, long); |
149 | extern unsigned long _ASR; | 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 | ||
150 | 169 | ||
151 | #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) | 170 | #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) |
152 | 171 | ||
@@ -186,47 +205,46 @@ Commands:\n\ | |||
186 | ml locate a block of memory\n\ | 205 | ml locate a block of memory\n\ |
187 | mz zero a block of memory\n\ | 206 | mz zero a block of memory\n\ |
188 | mi show information about memory allocation\n\ | 207 | mi show information about memory allocation\n\ |
189 | p show the task list\n\ | 208 | p call a procedure\n\ |
190 | r print registers\n\ | 209 | r print registers\n\ |
191 | s single step\n\ | 210 | s single step\n\ |
192 | S print special registers\n\ | 211 | S print special registers\n\ |
193 | t print backtrace\n\ | 212 | t print backtrace\n\ |
194 | T Enable/Disable PPCDBG flags\n\ | 213 | T Enable/Disable PPCDBG flags\n\ |
195 | x exit monitor and recover\n\ | 214 | x exit monitor and recover\n\ |
196 | X exit monitor and dont recover\n\ | 215 | X exit monitor and dont recover\n" |
197 | u dump segment table or SLB\n\ | 216 | #ifdef CONFIG_PPC64 |
198 | ? help\n" | 217 | " u dump segment table or SLB\n" |
199 | "\ | 218 | #endif |
200 | zr reboot\n\ | 219 | #ifdef CONFIG_PPC_STD_MMU_32 |
220 | " u dump segment registers\n" | ||
221 | #endif | ||
222 | " ? help\n" | ||
223 | " zr reboot\n\ | ||
201 | zh halt\n" | 224 | zh halt\n" |
202 | ; | 225 | ; |
203 | 226 | ||
204 | static struct pt_regs *xmon_regs; | 227 | static struct pt_regs *xmon_regs; |
205 | 228 | ||
206 | extern inline void sync(void) | 229 | static inline void sync(void) |
207 | { | 230 | { |
208 | asm volatile("sync; isync"); | 231 | asm volatile("sync; isync"); |
209 | } | 232 | } |
210 | 233 | ||
211 | /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs). | 234 | static inline void store_inst(void *p) |
212 | A PPC stack frame looks like this: | 235 | { |
213 | 236 | asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); | |
214 | High Address | 237 | } |
215 | Back Chain | 238 | |
216 | FP reg save area | 239 | static inline void cflush(void *p) |
217 | GP reg save area | 240 | { |
218 | Local var space | 241 | asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); |
219 | Parameter save area (SP+48) | 242 | } |
220 | TOC save area (SP+40) | 243 | |
221 | link editor doubleword (SP+32) | 244 | static inline void cinval(void *p) |
222 | compiler doubleword (SP+24) | 245 | { |
223 | LR save (SP+16) | 246 | asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); |
224 | CR save (SP+8) | 247 | } |
225 | Back Chain (SP+0) | ||
226 | |||
227 | Note that the LR (ret addr) may not be saved in the current frame if | ||
228 | no functions have been called from the current function. | ||
229 | */ | ||
230 | 248 | ||
231 | /* | 249 | /* |
232 | * Disable surveillance (the service processor watchdog function) | 250 | * Disable surveillance (the service processor watchdog function) |
@@ -310,8 +328,8 @@ int xmon_core(struct pt_regs *regs, int fromipi) | |||
310 | unsigned long timeout; | 328 | unsigned long timeout; |
311 | #endif | 329 | #endif |
312 | 330 | ||
313 | msr = get_msr(); | 331 | msr = mfmsr(); |
314 | set_msrd(msr & ~MSR_EE); /* disable interrupts */ | 332 | mtmsr(msr & ~MSR_EE); /* disable interrupts */ |
315 | 333 | ||
316 | bp = in_breakpoint_table(regs->nip, &offset); | 334 | bp = in_breakpoint_table(regs->nip, &offset); |
317 | if (bp != NULL) { | 335 | if (bp != NULL) { |
@@ -487,7 +505,7 @@ int xmon_core(struct pt_regs *regs, int fromipi) | |||
487 | 505 | ||
488 | insert_cpu_bpts(); | 506 | insert_cpu_bpts(); |
489 | 507 | ||
490 | set_msrd(msr); /* restore interrupt enable */ | 508 | mtmsr(msr); /* restore interrupt enable */ |
491 | 509 | ||
492 | return cmd != 'X'; | 510 | return cmd != 'X'; |
493 | } | 511 | } |
@@ -497,56 +515,23 @@ int xmon(struct pt_regs *excp) | |||
497 | struct pt_regs regs; | 515 | struct pt_regs regs; |
498 | 516 | ||
499 | if (excp == NULL) { | 517 | if (excp == NULL) { |
500 | /* Ok, grab regs as they are now. | 518 | xmon_save_regs(®s); |
501 | This won't do a particularily good job because the | ||
502 | prologue has already been executed. | ||
503 | ToDo: We could reach back into the callers save | ||
504 | area to do a better job of representing the | ||
505 | caller's state. | ||
506 | */ | ||
507 | asm volatile ("std 0,0(%0)\n\ | ||
508 | std 1,8(%0)\n\ | ||
509 | std 2,16(%0)\n\ | ||
510 | std 3,24(%0)\n\ | ||
511 | std 4,32(%0)\n\ | ||
512 | std 5,40(%0)\n\ | ||
513 | std 6,48(%0)\n\ | ||
514 | std 7,56(%0)\n\ | ||
515 | std 8,64(%0)\n\ | ||
516 | std 9,72(%0)\n\ | ||
517 | std 10,80(%0)\n\ | ||
518 | std 11,88(%0)\n\ | ||
519 | std 12,96(%0)\n\ | ||
520 | std 13,104(%0)\n\ | ||
521 | std 14,112(%0)\n\ | ||
522 | std 15,120(%0)\n\ | ||
523 | std 16,128(%0)\n\ | ||
524 | std 17,136(%0)\n\ | ||
525 | std 18,144(%0)\n\ | ||
526 | std 19,152(%0)\n\ | ||
527 | std 20,160(%0)\n\ | ||
528 | std 21,168(%0)\n\ | ||
529 | std 22,176(%0)\n\ | ||
530 | std 23,184(%0)\n\ | ||
531 | std 24,192(%0)\n\ | ||
532 | std 25,200(%0)\n\ | ||
533 | std 26,208(%0)\n\ | ||
534 | std 27,216(%0)\n\ | ||
535 | std 28,224(%0)\n\ | ||
536 | std 29,232(%0)\n\ | ||
537 | std 30,240(%0)\n\ | ||
538 | std 31,248(%0)" : : "b" (®s)); | ||
539 | |||
540 | regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2]; | ||
541 | regs.msr = get_msr(); | ||
542 | regs.ctr = get_ctr(); | ||
543 | regs.xer = get_xer(); | ||
544 | regs.ccr = get_cr(); | ||
545 | regs.trap = 0; | ||
546 | excp = ®s; | 519 | excp = ®s; |
547 | } | 520 | } |
548 | return xmon_core(excp, 0); | 521 | return xmon_core(excp, 0); |
549 | } | 522 | } |
523 | EXPORT_SYMBOL(xmon); | ||
524 | |||
525 | irqreturn_t | ||
526 | xmon_irq(int irq, void *d, struct pt_regs *regs) | ||
527 | { | ||
528 | unsigned long flags; | ||
529 | local_irq_save(flags); | ||
530 | printf("Keyboard interrupt\n"); | ||
531 | xmon(regs); | ||
532 | local_irq_restore(flags); | ||
533 | return IRQ_HANDLED; | ||
534 | } | ||
550 | 535 | ||
551 | int xmon_bpt(struct pt_regs *regs) | 536 | int xmon_bpt(struct pt_regs *regs) |
552 | { | 537 | { |
@@ -718,7 +703,7 @@ static void insert_cpu_bpts(void) | |||
718 | if (dabr.enabled) | 703 | if (dabr.enabled) |
719 | set_dabr(dabr.address | (dabr.enabled & 7)); | 704 | set_dabr(dabr.address | (dabr.enabled & 7)); |
720 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) | 705 | if (iabr && cpu_has_feature(CPU_FTR_IABR)) |
721 | set_iabr(iabr->address | 706 | mtspr(SPRN_IABR, iabr->address |
722 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); | 707 | | (iabr->enabled & (BP_IABR|BP_IABR_TE))); |
723 | } | 708 | } |
724 | 709 | ||
@@ -746,7 +731,7 @@ static void remove_cpu_bpts(void) | |||
746 | { | 731 | { |
747 | set_dabr(0); | 732 | set_dabr(0); |
748 | if (cpu_has_feature(CPU_FTR_IABR)) | 733 | if (cpu_has_feature(CPU_FTR_IABR)) |
749 | set_iabr(0); | 734 | mtspr(SPRN_IABR, 0); |
750 | } | 735 | } |
751 | 736 | ||
752 | /* Command interpreting routine */ | 737 | /* Command interpreting routine */ |
@@ -830,9 +815,6 @@ cmds(struct pt_regs *excp) | |||
830 | case '?': | 815 | case '?': |
831 | printf(help_string); | 816 | printf(help_string); |
832 | break; | 817 | break; |
833 | case 'p': | ||
834 | show_state(); | ||
835 | break; | ||
836 | case 'b': | 818 | case 'b': |
837 | bpt_cmds(); | 819 | bpt_cmds(); |
838 | break; | 820 | break; |
@@ -846,12 +828,14 @@ cmds(struct pt_regs *excp) | |||
846 | case 'z': | 828 | case 'z': |
847 | bootcmds(); | 829 | bootcmds(); |
848 | break; | 830 | break; |
849 | case 'T': | 831 | case 'p': |
850 | debug_trace(); | 832 | proccall(); |
851 | break; | 833 | break; |
834 | #ifdef CONFIG_PPC_STD_MMU | ||
852 | case 'u': | 835 | case 'u': |
853 | dump_segments(); | 836 | dump_segments(); |
854 | break; | 837 | break; |
838 | #endif | ||
855 | default: | 839 | default: |
856 | printf("Unrecognized command: "); | 840 | printf("Unrecognized command: "); |
857 | do { | 841 | do { |
@@ -1070,6 +1054,7 @@ bpt_cmds(void) | |||
1070 | 1054 | ||
1071 | cmd = inchar(); | 1055 | cmd = inchar(); |
1072 | switch (cmd) { | 1056 | switch (cmd) { |
1057 | #ifndef CONFIG_8xx | ||
1073 | case 'd': /* bd - hardware data breakpoint */ | 1058 | case 'd': /* bd - hardware data breakpoint */ |
1074 | mode = 7; | 1059 | mode = 7; |
1075 | cmd = inchar(); | 1060 | cmd = inchar(); |
@@ -1111,6 +1096,7 @@ bpt_cmds(void) | |||
1111 | iabr = bp; | 1096 | iabr = bp; |
1112 | } | 1097 | } |
1113 | break; | 1098 | break; |
1099 | #endif | ||
1114 | 1100 | ||
1115 | case 'c': | 1101 | case 'c': |
1116 | if (!scanhex(&a)) { | 1102 | if (!scanhex(&a)) { |
@@ -1152,7 +1138,7 @@ bpt_cmds(void) | |||
1152 | /* print all breakpoints */ | 1138 | /* print all breakpoints */ |
1153 | printf(" type address\n"); | 1139 | printf(" type address\n"); |
1154 | if (dabr.enabled) { | 1140 | if (dabr.enabled) { |
1155 | printf(" data %.16lx [", dabr.address); | 1141 | printf(" data "REG" [", dabr.address); |
1156 | if (dabr.enabled & 1) | 1142 | if (dabr.enabled & 1) |
1157 | printf("r"); | 1143 | printf("r"); |
1158 | if (dabr.enabled & 2) | 1144 | if (dabr.enabled & 2) |
@@ -1231,6 +1217,18 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp, | |||
1231 | 1217 | ||
1232 | static int xmon_depth_to_print = 64; | 1218 | static int xmon_depth_to_print = 64; |
1233 | 1219 | ||
1220 | #ifdef CONFIG_PPC64 | ||
1221 | #define LRSAVE_OFFSET 0x10 | ||
1222 | #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ | ||
1223 | #define MARKER_OFFSET 0x60 | ||
1224 | #define REGS_OFFSET 0x70 | ||
1225 | #else | ||
1226 | #define LRSAVE_OFFSET 4 | ||
1227 | #define REG_FRAME_MARKER 0x72656773 | ||
1228 | #define MARKER_OFFSET 8 | ||
1229 | #define REGS_OFFSET 16 | ||
1230 | #endif | ||
1231 | |||
1234 | static void xmon_show_stack(unsigned long sp, unsigned long lr, | 1232 | static void xmon_show_stack(unsigned long sp, unsigned long lr, |
1235 | unsigned long pc) | 1233 | unsigned long pc) |
1236 | { | 1234 | { |
@@ -1247,7 +1245,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, | |||
1247 | break; | 1245 | break; |
1248 | } | 1246 | } |
1249 | 1247 | ||
1250 | if (!mread(sp + 16, &ip, sizeof(unsigned long)) | 1248 | if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) |
1251 | || !mread(sp, &newsp, sizeof(unsigned long))) { | 1249 | || !mread(sp, &newsp, sizeof(unsigned long))) { |
1252 | printf("Couldn't read stack frame at %lx\n", sp); | 1250 | printf("Couldn't read stack frame at %lx\n", sp); |
1253 | break; | 1251 | break; |
@@ -1266,7 +1264,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, | |||
1266 | get_function_bounds(pc, &fnstart, &fnend); | 1264 | get_function_bounds(pc, &fnstart, &fnend); |
1267 | nextip = 0; | 1265 | nextip = 0; |
1268 | if (newsp > sp) | 1266 | if (newsp > sp) |
1269 | mread(newsp + 16, &nextip, | 1267 | mread(newsp + LRSAVE_OFFSET, &nextip, |
1270 | sizeof(unsigned long)); | 1268 | sizeof(unsigned long)); |
1271 | if (lr == ip) { | 1269 | if (lr == ip) { |
1272 | if (lr < PAGE_OFFSET | 1270 | if (lr < PAGE_OFFSET |
@@ -1280,24 +1278,24 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr, | |||
1280 | xmon_print_symbol(lr, " ", "\n"); | 1278 | xmon_print_symbol(lr, " ", "\n"); |
1281 | } | 1279 | } |
1282 | if (printip) { | 1280 | if (printip) { |
1283 | printf("[%.16lx] ", sp); | 1281 | printf("["REG"] ", sp); |
1284 | xmon_print_symbol(ip, " ", " (unreliable)\n"); | 1282 | xmon_print_symbol(ip, " ", " (unreliable)\n"); |
1285 | } | 1283 | } |
1286 | pc = lr = 0; | 1284 | pc = lr = 0; |
1287 | 1285 | ||
1288 | } else { | 1286 | } else { |
1289 | printf("[%.16lx] ", sp); | 1287 | printf("["REG"] ", sp); |
1290 | xmon_print_symbol(ip, " ", "\n"); | 1288 | xmon_print_symbol(ip, " ", "\n"); |
1291 | } | 1289 | } |
1292 | 1290 | ||
1293 | /* Look for "regshere" marker to see if this is | 1291 | /* Look for "regshere" marker to see if this is |
1294 | an exception frame. */ | 1292 | an exception frame. */ |
1295 | if (mread(sp + 0x60, &marker, sizeof(unsigned long)) | 1293 | if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) |
1296 | && marker == 0x7265677368657265ul) { | 1294 | && marker == REG_FRAME_MARKER) { |
1297 | if (mread(sp + 0x70, ®s, sizeof(regs)) | 1295 | if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) |
1298 | != sizeof(regs)) { | 1296 | != sizeof(regs)) { |
1299 | printf("Couldn't read registers at %lx\n", | 1297 | printf("Couldn't read registers at %lx\n", |
1300 | sp + 0x70); | 1298 | sp + REGS_OFFSET); |
1301 | break; | 1299 | break; |
1302 | } | 1300 | } |
1303 | printf("--- Exception: %lx %s at ", regs.trap, | 1301 | printf("--- Exception: %lx %s at ", regs.trap, |
@@ -1371,7 +1369,9 @@ void excprint(struct pt_regs *fp) | |||
1371 | } | 1369 | } |
1372 | 1370 | ||
1373 | printf(" current = 0x%lx\n", current); | 1371 | printf(" current = 0x%lx\n", current); |
1372 | #ifdef CONFIG_PPC64 | ||
1374 | printf(" paca = 0x%lx\n", get_paca()); | 1373 | printf(" paca = 0x%lx\n", get_paca()); |
1374 | #endif | ||
1375 | if (current) { | 1375 | if (current) { |
1376 | printf(" pid = %ld, comm = %s\n", | 1376 | printf(" pid = %ld, comm = %s\n", |
1377 | current->pid, current->comm); | 1377 | current->pid, current->comm); |
@@ -1383,7 +1383,7 @@ void excprint(struct pt_regs *fp) | |||
1383 | 1383 | ||
1384 | void prregs(struct pt_regs *fp) | 1384 | void prregs(struct pt_regs *fp) |
1385 | { | 1385 | { |
1386 | int n; | 1386 | int n, trap; |
1387 | unsigned long base; | 1387 | unsigned long base; |
1388 | struct pt_regs regs; | 1388 | struct pt_regs regs; |
1389 | 1389 | ||
@@ -1396,7 +1396,7 @@ void prregs(struct pt_regs *fp) | |||
1396 | __delay(200); | 1396 | __delay(200); |
1397 | } else { | 1397 | } else { |
1398 | catch_memory_errors = 0; | 1398 | catch_memory_errors = 0; |
1399 | printf("*** Error reading registers from %.16lx\n", | 1399 | printf("*** Error reading registers from "REG"\n", |
1400 | base); | 1400 | base); |
1401 | return; | 1401 | return; |
1402 | } | 1402 | } |
@@ -1404,22 +1404,36 @@ void prregs(struct pt_regs *fp) | |||
1404 | fp = ®s; | 1404 | fp = ®s; |
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | #ifdef CONFIG_PPC64 | ||
1407 | if (FULL_REGS(fp)) { | 1408 | if (FULL_REGS(fp)) { |
1408 | for (n = 0; n < 16; ++n) | 1409 | for (n = 0; n < 16; ++n) |
1409 | printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", | 1410 | printf("R%.2ld = "REG" R%.2ld = "REG"\n", |
1410 | n, fp->gpr[n], n+16, fp->gpr[n+16]); | 1411 | n, fp->gpr[n], n+16, fp->gpr[n+16]); |
1411 | } else { | 1412 | } else { |
1412 | for (n = 0; n < 7; ++n) | 1413 | for (n = 0; n < 7; ++n) |
1413 | printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", | 1414 | printf("R%.2ld = "REG" R%.2ld = "REG"\n", |
1414 | n, fp->gpr[n], n+7, fp->gpr[n+7]); | 1415 | n, fp->gpr[n], n+7, fp->gpr[n+7]); |
1415 | } | 1416 | } |
1417 | #else | ||
1418 | for (n = 0; n < 32; ++n) { | ||
1419 | printf("R%.2d = %.8x%s", n, fp->gpr[n], | ||
1420 | (n & 3) == 3? "\n": " "); | ||
1421 | if (n == 12 && !FULL_REGS(fp)) { | ||
1422 | printf("\n"); | ||
1423 | break; | ||
1424 | } | ||
1425 | } | ||
1426 | #endif | ||
1416 | printf("pc = "); | 1427 | printf("pc = "); |
1417 | xmon_print_symbol(fp->nip, " ", "\n"); | 1428 | xmon_print_symbol(fp->nip, " ", "\n"); |
1418 | printf("lr = "); | 1429 | printf("lr = "); |
1419 | xmon_print_symbol(fp->link, " ", "\n"); | 1430 | xmon_print_symbol(fp->link, " ", "\n"); |
1420 | printf("msr = %.16lx cr = %.8lx\n", fp->msr, fp->ccr); | 1431 | printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); |
1421 | printf("ctr = %.16lx xer = %.16lx trap = %8lx\n", | 1432 | printf("ctr = "REG" xer = "REG" trap = %4lx\n", |
1422 | fp->ctr, fp->xer, fp->trap); | 1433 | fp->ctr, fp->xer, fp->trap); |
1434 | trap = TRAP(fp); | ||
1435 | if (trap == 0x300 || trap == 0x380 || trap == 0x600) | ||
1436 | printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); | ||
1423 | } | 1437 | } |
1424 | 1438 | ||
1425 | void cacheflush(void) | 1439 | void cacheflush(void) |
@@ -1519,8 +1533,7 @@ static unsigned long regno; | |||
1519 | extern char exc_prolog; | 1533 | extern char exc_prolog; |
1520 | extern char dec_exc; | 1534 | extern char dec_exc; |
1521 | 1535 | ||
1522 | void | 1536 | void super_regs(void) |
1523 | super_regs(void) | ||
1524 | { | 1537 | { |
1525 | int cmd; | 1538 | int cmd; |
1526 | unsigned long val; | 1539 | unsigned long val; |
@@ -1536,12 +1549,14 @@ super_regs(void) | |||
1536 | asm("mr %0,1" : "=r" (sp) :); | 1549 | asm("mr %0,1" : "=r" (sp) :); |
1537 | asm("mr %0,2" : "=r" (toc) :); | 1550 | asm("mr %0,2" : "=r" (toc) :); |
1538 | 1551 | ||
1539 | printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0()); | 1552 | printf("msr = "REG" sprg0= "REG"\n", |
1540 | printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1()); | 1553 | mfmsr(), mfspr(SPRN_SPRG0)); |
1541 | printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2()); | 1554 | printf("pvr = "REG" sprg1= "REG"\n", |
1542 | printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3()); | 1555 | mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); |
1543 | printf("toc = %.16lx dar = %.16lx\n", toc, get_dar()); | 1556 | printf("dec = "REG" sprg2= "REG"\n", |
1544 | printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1()); | 1557 | mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); |
1558 | printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); | ||
1559 | printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); | ||
1545 | #ifdef CONFIG_PPC_ISERIES | 1560 | #ifdef CONFIG_PPC_ISERIES |
1546 | // Dump out relevant Paca data areas. | 1561 | // Dump out relevant Paca data areas. |
1547 | printf("Paca: \n"); | 1562 | printf("Paca: \n"); |
@@ -1578,11 +1593,6 @@ super_regs(void) | |||
1578 | case 'r': | 1593 | case 'r': |
1579 | printf("spr %lx = %lx\n", regno, read_spr(regno)); | 1594 | printf("spr %lx = %lx\n", regno, read_spr(regno)); |
1580 | break; | 1595 | break; |
1581 | case 'm': | ||
1582 | val = get_msr(); | ||
1583 | scanhex(&val); | ||
1584 | set_msrd(val); | ||
1585 | break; | ||
1586 | } | 1596 | } |
1587 | scannl(); | 1597 | scannl(); |
1588 | } | 1598 | } |
@@ -1604,13 +1614,13 @@ mread(unsigned long adrs, void *buf, int size) | |||
1604 | q = (char *)buf; | 1614 | q = (char *)buf; |
1605 | switch (size) { | 1615 | switch (size) { |
1606 | case 2: | 1616 | case 2: |
1607 | *(short *)q = *(short *)p; | 1617 | *(u16 *)q = *(u16 *)p; |
1608 | break; | 1618 | break; |
1609 | case 4: | 1619 | case 4: |
1610 | *(int *)q = *(int *)p; | 1620 | *(u32 *)q = *(u32 *)p; |
1611 | break; | 1621 | break; |
1612 | case 8: | 1622 | case 8: |
1613 | *(long *)q = *(long *)p; | 1623 | *(u64 *)q = *(u64 *)p; |
1614 | break; | 1624 | break; |
1615 | default: | 1625 | default: |
1616 | for( ; n < size; ++n) { | 1626 | for( ; n < size; ++n) { |
@@ -1641,13 +1651,13 @@ mwrite(unsigned long adrs, void *buf, int size) | |||
1641 | q = (char *) buf; | 1651 | q = (char *) buf; |
1642 | switch (size) { | 1652 | switch (size) { |
1643 | case 2: | 1653 | case 2: |
1644 | *(short *)p = *(short *)q; | 1654 | *(u16 *)p = *(u16 *)q; |
1645 | break; | 1655 | break; |
1646 | case 4: | 1656 | case 4: |
1647 | *(int *)p = *(int *)q; | 1657 | *(u32 *)p = *(u32 *)q; |
1648 | break; | 1658 | break; |
1649 | case 8: | 1659 | case 8: |
1650 | *(long *)p = *(long *)q; | 1660 | *(u64 *)p = *(u64 *)q; |
1651 | break; | 1661 | break; |
1652 | default: | 1662 | default: |
1653 | for ( ; n < size; ++n) { | 1663 | for ( ; n < size; ++n) { |
@@ -1667,11 +1677,12 @@ mwrite(unsigned long adrs, void *buf, int size) | |||
1667 | } | 1677 | } |
1668 | 1678 | ||
1669 | static int fault_type; | 1679 | static int fault_type; |
1680 | static int fault_except; | ||
1670 | static char *fault_chars[] = { "--", "**", "##" }; | 1681 | static char *fault_chars[] = { "--", "**", "##" }; |
1671 | 1682 | ||
1672 | static int | 1683 | static int handle_fault(struct pt_regs *regs) |
1673 | handle_fault(struct pt_regs *regs) | ||
1674 | { | 1684 | { |
1685 | fault_except = TRAP(regs); | ||
1675 | switch (TRAP(regs)) { | 1686 | switch (TRAP(regs)) { |
1676 | case 0x200: | 1687 | case 0x200: |
1677 | fault_type = 0; | 1688 | fault_type = 0; |
@@ -1960,7 +1971,7 @@ prdump(unsigned long adrs, long ndump) | |||
1960 | unsigned char temp[16]; | 1971 | unsigned char temp[16]; |
1961 | 1972 | ||
1962 | for (n = ndump; n > 0;) { | 1973 | for (n = ndump; n > 0;) { |
1963 | printf("%.16lx", adrs); | 1974 | printf(REG, adrs); |
1964 | putchar(' '); | 1975 | putchar(' '); |
1965 | r = n < 16? n: 16; | 1976 | r = n < 16? n: 16; |
1966 | nr = mread(adrs, temp, r); | 1977 | nr = mread(adrs, temp, r); |
@@ -2008,7 +2019,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr) | |||
2008 | if (nr == 0) { | 2019 | if (nr == 0) { |
2009 | if (praddr) { | 2020 | if (praddr) { |
2010 | const char *x = fault_chars[fault_type]; | 2021 | const char *x = fault_chars[fault_type]; |
2011 | printf("%.16lx %s%s%s%s\n", adr, x, x, x, x); | 2022 | printf(REG" %s%s%s%s\n", adr, x, x, x, x); |
2012 | } | 2023 | } |
2013 | break; | 2024 | break; |
2014 | } | 2025 | } |
@@ -2023,7 +2034,7 @@ ppc_inst_dump(unsigned long adr, long count, int praddr) | |||
2023 | dotted = 0; | 2034 | dotted = 0; |
2024 | last_inst = inst; | 2035 | last_inst = inst; |
2025 | if (praddr) | 2036 | if (praddr) |
2026 | printf("%.16lx %.8x", adr, inst); | 2037 | printf(REG" %.8x", adr, inst); |
2027 | printf("\t"); | 2038 | printf("\t"); |
2028 | print_insn_powerpc(inst, adr, 0); /* always returns 4 */ | 2039 | print_insn_powerpc(inst, adr, 0); /* always returns 4 */ |
2029 | printf("\n"); | 2040 | printf("\n"); |
@@ -2152,6 +2163,42 @@ memzcan(void) | |||
2152 | printf("%.8x\n", a - mskip); | 2163 | printf("%.8x\n", a - mskip); |
2153 | } | 2164 | } |
2154 | 2165 | ||
2166 | void proccall(void) | ||
2167 | { | ||
2168 | unsigned long args[8]; | ||
2169 | unsigned long ret; | ||
2170 | int i; | ||
2171 | typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, | ||
2172 | unsigned long, unsigned long, unsigned long, | ||
2173 | unsigned long, unsigned long, unsigned long); | ||
2174 | callfunc_t func; | ||
2175 | |||
2176 | if (!scanhex(&adrs)) | ||
2177 | return; | ||
2178 | if (termch != '\n') | ||
2179 | termch = 0; | ||
2180 | for (i = 0; i < 8; ++i) | ||
2181 | args[i] = 0; | ||
2182 | for (i = 0; i < 8; ++i) { | ||
2183 | if (!scanhex(&args[i]) || termch == '\n') | ||
2184 | break; | ||
2185 | termch = 0; | ||
2186 | } | ||
2187 | func = (callfunc_t) adrs; | ||
2188 | ret = 0; | ||
2189 | if (setjmp(bus_error_jmp) == 0) { | ||
2190 | catch_memory_errors = 1; | ||
2191 | sync(); | ||
2192 | ret = func(args[0], args[1], args[2], args[3], | ||
2193 | args[4], args[5], args[6], args[7]); | ||
2194 | sync(); | ||
2195 | printf("return value is %x\n", ret); | ||
2196 | } else { | ||
2197 | printf("*** %x exception occurred\n", fault_except); | ||
2198 | } | ||
2199 | catch_memory_errors = 0; | ||
2200 | } | ||
2201 | |||
2155 | /* Input scanning routines */ | 2202 | /* Input scanning routines */ |
2156 | int | 2203 | int |
2157 | skipbl(void) | 2204 | skipbl(void) |
@@ -2174,7 +2221,12 @@ static char *regnames[N_PTREGS] = { | |||
2174 | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", | 2221 | "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", |
2175 | "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", | 2222 | "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", |
2176 | "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", | 2223 | "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", |
2177 | "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe", | 2224 | "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", |
2225 | #ifdef CONFIG_PPC64 | ||
2226 | "softe", | ||
2227 | #else | ||
2228 | "mq", | ||
2229 | #endif | ||
2178 | "trap", "dar", "dsisr", "res" | 2230 | "trap", "dar", "dsisr", "res" |
2179 | }; | 2231 | }; |
2180 | 2232 | ||
@@ -2280,8 +2332,7 @@ scannl(void) | |||
2280 | c = inchar(); | 2332 | c = inchar(); |
2281 | } | 2333 | } |
2282 | 2334 | ||
2283 | int | 2335 | int hexdigit(int c) |
2284 | hexdigit(int c) | ||
2285 | { | 2336 | { |
2286 | if( '0' <= c && c <= '9' ) | 2337 | if( '0' <= c && c <= '9' ) |
2287 | return c - '0'; | 2338 | return c - '0'; |
@@ -2378,7 +2429,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, | |||
2378 | const char *name = NULL; | 2429 | const char *name = NULL; |
2379 | unsigned long offset, size; | 2430 | unsigned long offset, size; |
2380 | 2431 | ||
2381 | printf("%.16lx", address); | 2432 | printf(REG, address); |
2382 | if (setjmp(bus_error_jmp) == 0) { | 2433 | if (setjmp(bus_error_jmp) == 0) { |
2383 | catch_memory_errors = 1; | 2434 | catch_memory_errors = 1; |
2384 | sync(); | 2435 | sync(); |
@@ -2399,55 +2450,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, | |||
2399 | printf("%s", after); | 2450 | printf("%s", after); |
2400 | } | 2451 | } |
2401 | 2452 | ||
2402 | static void debug_trace(void) | 2453 | #ifdef CONFIG_PPC64 |
2403 | { | ||
2404 | unsigned long val, cmd, on; | ||
2405 | |||
2406 | cmd = skipbl(); | ||
2407 | if (cmd == '\n') { | ||
2408 | /* show current state */ | ||
2409 | unsigned long i; | ||
2410 | printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch); | ||
2411 | for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) { | ||
2412 | on = PPCDBG_BITVAL(i) & ppc64_debug_switch; | ||
2413 | printf("%02x %s %12s ", i, on ? "on " : "off", trace_names[i] ? trace_names[i] : ""); | ||
2414 | if (((i+1) % 3) == 0) | ||
2415 | printf("\n"); | ||
2416 | } | ||
2417 | printf("\n"); | ||
2418 | return; | ||
2419 | } | ||
2420 | while (cmd != '\n') { | ||
2421 | on = 1; /* default if no sign given */ | ||
2422 | while (cmd == '+' || cmd == '-') { | ||
2423 | on = (cmd == '+'); | ||
2424 | cmd = inchar(); | ||
2425 | if (cmd == ' ' || cmd == '\n') { /* Turn on or off based on + or - */ | ||
2426 | ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE; | ||
2427 | printf("Setting all values to %s...\n", on ? "on" : "off"); | ||
2428 | if (cmd == '\n') return; | ||
2429 | else cmd = skipbl(); | ||
2430 | } | ||
2431 | else | ||
2432 | termch = cmd; | ||
2433 | } | ||
2434 | termch = cmd; /* not +/- ... let scanhex see it */ | ||
2435 | scanhex((void *)&val); | ||
2436 | if (val >= 64) { | ||
2437 | printf("Value %x out of range:\n", val); | ||
2438 | return; | ||
2439 | } | ||
2440 | if (on) { | ||
2441 | ppc64_debug_switch |= PPCDBG_BITVAL(val); | ||
2442 | printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); | ||
2443 | } else { | ||
2444 | ppc64_debug_switch &= ~PPCDBG_BITVAL(val); | ||
2445 | printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : ""); | ||
2446 | } | ||
2447 | cmd = skipbl(); | ||
2448 | } | ||
2449 | } | ||
2450 | |||
2451 | static void dump_slb(void) | 2454 | static void dump_slb(void) |
2452 | { | 2455 | { |
2453 | int i; | 2456 | int i; |
@@ -2484,6 +2487,27 @@ static void dump_stab(void) | |||
2484 | } | 2487 | } |
2485 | } | 2488 | } |
2486 | 2489 | ||
2490 | void dump_segments(void) | ||
2491 | { | ||
2492 | if (cpu_has_feature(CPU_FTR_SLB)) | ||
2493 | dump_slb(); | ||
2494 | else | ||
2495 | dump_stab(); | ||
2496 | } | ||
2497 | #endif | ||
2498 | |||
2499 | #ifdef CONFIG_PPC_STD_MMU_32 | ||
2500 | void dump_segments(void) | ||
2501 | { | ||
2502 | int i; | ||
2503 | |||
2504 | printf("sr0-15 ="); | ||
2505 | for (i = 0; i < 16; ++i) | ||
2506 | printf(" %x", mfsrin(i)); | ||
2507 | printf("\n"); | ||
2508 | } | ||
2509 | #endif | ||
2510 | |||
2487 | void xmon_init(int enable) | 2511 | void xmon_init(int enable) |
2488 | { | 2512 | { |
2489 | if (enable) { | 2513 | if (enable) { |
@@ -2504,11 +2528,3 @@ void xmon_init(int enable) | |||
2504 | __debugger_fault_handler = NULL; | 2528 | __debugger_fault_handler = NULL; |
2505 | } | 2529 | } |
2506 | } | 2530 | } |
2507 | |||
2508 | void dump_segments(void) | ||
2509 | { | ||
2510 | if (cpu_has_feature(CPU_FTR_SLB)) | ||
2511 | dump_slb(); | ||
2512 | else | ||
2513 | dump_stab(); | ||
2514 | } | ||
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 2a7af765bfb6..743f0dbdebf3 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
@@ -89,7 +89,7 @@ core-y += arch/powerpc/mm/ | |||
89 | core-y += arch/powerpc/sysdev/ | 89 | core-y += arch/powerpc/sysdev/ |
90 | core-y += arch/powerpc/platforms/ | 90 | core-y += arch/powerpc/platforms/ |
91 | core-y += arch/powerpc/lib/ | 91 | core-y += arch/powerpc/lib/ |
92 | core-$(CONFIG_XMON) += arch/ppc64/xmon/ | 92 | core-$(CONFIG_XMON) += arch/powerpc/xmon/ |
93 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | 93 | drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ |
94 | 94 | ||
95 | boot := arch/ppc64/boot | 95 | boot := arch/ppc64/boot |
diff --git a/arch/ppc64/xmon/Makefile b/arch/ppc64/xmon/Makefile deleted file mode 100644 index fb21a7088d3e..000000000000 --- a/arch/ppc64/xmon/Makefile +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | # Makefile for xmon | ||
2 | |||
3 | EXTRA_CFLAGS += -mno-minimal-toc | ||
4 | |||
5 | obj-y := start.o xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o | ||
diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S deleted file mode 100644 index 30ee643d557c..000000000000 --- a/arch/ppc64/xmon/setjmp.S +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Paul Mackerras. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: assert(sizeof(buf) > 184) | ||
10 | */ | ||
11 | #include <asm/processor.h> | ||
12 | #include <asm/ppc_asm.h> | ||
13 | |||
14 | _GLOBAL(xmon_setjmp) | ||
15 | mflr r0 | ||
16 | std r0,0(r3) | ||
17 | std r1,8(r3) | ||
18 | std r2,16(r3) | ||
19 | mfcr r0 | ||
20 | std r0,24(r3) | ||
21 | std r13,32(r3) | ||
22 | std r14,40(r3) | ||
23 | std r15,48(r3) | ||
24 | std r16,56(r3) | ||
25 | std r17,64(r3) | ||
26 | std r18,72(r3) | ||
27 | std r19,80(r3) | ||
28 | std r20,88(r3) | ||
29 | std r21,96(r3) | ||
30 | std r22,104(r3) | ||
31 | std r23,112(r3) | ||
32 | std r24,120(r3) | ||
33 | std r25,128(r3) | ||
34 | std r26,136(r3) | ||
35 | std r27,144(r3) | ||
36 | std r28,152(r3) | ||
37 | std r29,160(r3) | ||
38 | std r30,168(r3) | ||
39 | std r31,176(r3) | ||
40 | li r3,0 | ||
41 | blr | ||
42 | |||
43 | _GLOBAL(xmon_longjmp) | ||
44 | cmpdi r4,0 | ||
45 | bne 1f | ||
46 | li r4,1 | ||
47 | 1: ld r13,32(r3) | ||
48 | ld r14,40(r3) | ||
49 | ld r15,48(r3) | ||
50 | ld r16,56(r3) | ||
51 | ld r17,64(r3) | ||
52 | ld r18,72(r3) | ||
53 | ld r19,80(r3) | ||
54 | ld r20,88(r3) | ||
55 | ld r21,96(r3) | ||
56 | ld r22,104(r3) | ||
57 | ld r23,112(r3) | ||
58 | ld r24,120(r3) | ||
59 | ld r25,128(r3) | ||
60 | ld r26,136(r3) | ||
61 | ld r27,144(r3) | ||
62 | ld r28,152(r3) | ||
63 | ld r29,160(r3) | ||
64 | ld r30,168(r3) | ||
65 | ld r31,176(r3) | ||
66 | ld r0,24(r3) | ||
67 | mtcrf 56,r0 | ||
68 | ld r0,0(r3) | ||
69 | ld r1,8(r3) | ||
70 | ld r2,16(r3) | ||
71 | mtlr r0 | ||
72 | mr r3,r4 | ||
73 | blr | ||
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h index 470d7400ac59..f99f2af82ca5 100644 --- a/include/asm-powerpc/ppc_asm.h +++ b/include/asm-powerpc/ppc_asm.h | |||
@@ -188,6 +188,10 @@ n: | |||
188 | #define LDL ld | 188 | #define LDL ld |
189 | #define STL std | 189 | #define STL std |
190 | #define CMPI cmpdi | 190 | #define CMPI cmpdi |
191 | #define SZL 8 | ||
192 | |||
193 | /* offsets for stack frame layout */ | ||
194 | #define LRSAVE 16 | ||
191 | 195 | ||
192 | #else /* 32-bit */ | 196 | #else /* 32-bit */ |
193 | #define LOADADDR(rn,name) \ | 197 | #define LOADADDR(rn,name) \ |
@@ -203,6 +207,10 @@ n: | |||
203 | #define LDL lwz | 207 | #define LDL lwz |
204 | #define STL stw | 208 | #define STL stw |
205 | #define CMPI cmpwi | 209 | #define CMPI cmpwi |
210 | #define SZL 4 | ||
211 | |||
212 | /* offsets for stack frame layout */ | ||
213 | #define LRSAVE 4 | ||
206 | 214 | ||
207 | #endif | 215 | #endif |
208 | 216 | ||
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index bfb45a4523d3..da848412f11b 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h | |||
@@ -546,6 +546,7 @@ | |||
546 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ | 546 | #define __mtmsrd(v, l) asm volatile("mtmsrd %0," __stringify(l) \ |
547 | : : "r" (v)) | 547 | : : "r" (v)) |
548 | #define mtmsrd(v) __mtmsrd((v), 0) | 548 | #define mtmsrd(v) __mtmsrd((v), 0) |
549 | #define mtmsr(v) mtmsrd(v) | ||
549 | #else | 550 | #else |
550 | #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) | 551 | #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) |
551 | #endif | 552 | #endif |
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h index ca5f33277e0c..43f7129984c7 100644 --- a/include/asm-powerpc/xmon.h +++ b/include/asm-powerpc/xmon.h | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | struct pt_regs; | 5 | struct pt_regs; |
6 | 6 | ||
7 | extern void xmon(struct pt_regs *excp); | 7 | extern int xmon(struct pt_regs *excp); |
8 | extern void xmon_printf(const char *fmt, ...); | 8 | extern void xmon_printf(const char *fmt, ...); |
9 | extern void xmon_init(int); | 9 | extern void xmon_init(int); |
10 | 10 | ||