aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-28 08:53:37 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-28 08:53:37 -0400
commitf78541dcec327b0c46b150ee7d727f3db80275c4 (patch)
tree9336801742d93ffa0c84c76e2b3cdc5b50c7125b
parentc032524f0ddea5fcc3a2cece0d4a61f37e5ca9cd (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>
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/kernel/head_32.S3
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c5
-rw-r--r--arch/powerpc/kernel/setup_32.c6
-rw-r--r--arch/powerpc/kernel/setup_64.c1
-rw-r--r--arch/powerpc/lib/Makefile2
-rw-r--r--arch/powerpc/xmon/Makefile11
-rw-r--r--arch/powerpc/xmon/ansidecl.h (renamed from arch/ppc64/xmon/ansidecl.h)0
-rw-r--r--arch/powerpc/xmon/nonstdio.h (renamed from arch/ppc64/xmon/nonstdio.h)0
-rw-r--r--arch/powerpc/xmon/ppc-dis.c (renamed from arch/ppc64/xmon/ppc-dis.c)0
-rw-r--r--arch/powerpc/xmon/ppc-opc.c (renamed from arch/ppc64/xmon/ppc-opc.c)0
-rw-r--r--arch/powerpc/xmon/ppc.h (renamed from arch/ppc64/xmon/ppc.h)0
-rw-r--r--arch/powerpc/xmon/setjmp.S135
-rw-r--r--arch/powerpc/xmon/start_32.c624
-rw-r--r--arch/powerpc/xmon/start_64.c (renamed from arch/ppc64/xmon/start.c)0
-rw-r--r--arch/powerpc/xmon/start_8xx.c287
-rw-r--r--arch/powerpc/xmon/subr_prf.c (renamed from arch/ppc64/xmon/subr_prf.c)11
-rw-r--r--arch/powerpc/xmon/xmon.c (renamed from arch/ppc64/xmon/xmon.c)398
-rw-r--r--arch/ppc64/Makefile2
-rw-r--r--arch/ppc64/xmon/Makefile5
-rw-r--r--arch/ppc64/xmon/setjmp.S73
-rw-r--r--include/asm-powerpc/ppc_asm.h8
-rw-r--r--include/asm-powerpc/reg.h1
-rw-r--r--include/asm-powerpc/xmon.h2
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/
133core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ 133core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
134#core-$(CONFIG_XMON) += arch/powerpc/xmon/ 134core-$(CONFIG_XMON) += arch/powerpc/xmon/
135core-$(CONFIG_APUS) += arch/ppc/amiga/ 135core-$(CONFIG_APUS) += arch/ppc/amiga/
136drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ 136drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
137drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ 137drivers-$(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);
238EXPORT_SYMBOL(cacheable_memcpy); 237EXPORT_SYMBOL(cacheable_memcpy);
239#endif 238#endif
240 239
241#ifdef CONFIG_XMON
242EXPORT_SYMBOL(xmon);
243EXPORT_SYMBOL(xmon_printf);
244#endif
245EXPORT_SYMBOL(__up); 240EXPORT_SYMBOL(__up);
246EXPORT_SYMBOL(__down); 241EXPORT_SYMBOL(__down);
247EXPORT_SYMBOL(__down_interruptible); 242EXPORT_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
11obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \ 11obj-$(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
13obj-$(CONFIG_PPC_ISERIES) += e2a.o 13obj-$(CONFIG_PPC_ISERIES) += e2a.o
14obj-$(CONFIG_XMON) += sstep.o
15
14ifeq ($(CONFIG_PPC64),y) 16ifeq ($(CONFIG_PPC64),y)
15obj-$(CONFIG_SMP) += locks.o 17obj-$(CONFIG_SMP) += locks.o
16obj-$(CONFIG_DEBUG_KERNEL) += sstep.o 18obj-$(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
3ifdef CONFIG_PPC64
4EXTRA_CFLAGS += -mno-minimal-toc
5endif
6
7obj-$(CONFIG_8xx) += start_8xx.o
8obj-$(CONFIG_6xx) += start_32.o
9obj-$(CONFIG_4xx) += start_32.o
10obj-$(CONFIG_PPC64) += start_64.o
11obj-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
481: 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
26static volatile unsigned char __iomem *sccc, *sccd;
27unsigned int TXRDY, RXRDY, DLAB;
28static int xmon_expect(const char *str, unsigned int timeout);
29
30static int use_serial;
31static int use_screen;
32static int via_modem;
33static int xmon_use_sccb;
34static struct device_node *channel_node;
35
36#define TB_SPEED 25000000
37
38static inline unsigned int readtb(void)
39{
40 unsigned int ret;
41
42 asm volatile("mftb %0" : "=r" (ret) :);
43 return ret;
44}
45
46void buf_access(void)
47{
48 if (DLAB)
49 sccd[3] &= ~DLAB; /* reset DLAB */
50}
51
52extern 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 */
60static 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
95static void sysrq_handle_xmon(int key, struct pt_regs *regs,
96 struct tty_struct *tty)
97{
98 xmon(regs);
99}
100
101static 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
109void
110xmon_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
224static int scc_initialized = 0;
225
226void xmon_init_scc(void);
227extern void cuda_poll(void);
228
229static 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
241int
242xmon_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
292int xmon_wants_key;
293int xmon_adb_keycode;
294
295#ifdef CONFIG_BOOTX_TEXT
296static int xmon_adb_shiftstate;
297
298static 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
306static 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
314static int
315xmon_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
353int
354xmon_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
377int
378xmon_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
388static 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
398void
399xmon_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
462void *xmon_stdin;
463void *xmon_stdout;
464void *xmon_stderr;
465
466int 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
475int xmon_putchar(int c)
476{
477 return xmon_putc(c, xmon_stdout);
478}
479
480int 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
487int
488xmon_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
503static char line[256];
504static char *lineptr;
505static int lineleft;
506
507int 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
533int
534xmon_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
585char *
586xmon_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
606void
607xmon_enter(void)
608{
609#ifdef CONFIG_ADB_PMU
610 if (_machine == _MACH_Pmac) {
611 pmu_suspend();
612 }
613#endif
614}
615
616void
617xmon_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
19extern void xmon_printf(const char *fmt, ...);
20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void);
23void prom_drawhex(uint);
24void prom_drawstring(const char *str);
25
26static int use_screen = 1; /* default */
27
28#define TB_SPEED 25000000
29
30static inline unsigned int readtb(void)
31{
32 unsigned int ret;
33
34 asm volatile("mftb %0" : "=r" (ret) :);
35 return ret;
36}
37
38void buf_access(void)
39{
40}
41
42void
43xmon_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
52static int scc_initialized = 0;
53
54void xmon_init_scc(void);
55
56int
57xmon_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
68int xmon_wants_key;
69
70int
71xmon_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
85int
86xmon_read_poll(void)
87{
88 return(xmon_8xx_read_poll());
89}
90
91void
92xmon_init_scc()
93{
94 scc_initialized = 1;
95}
96
97#if 0
98extern int (*prom_entry)(void *);
99
100int
101xmon_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
114void *xmon_stdin;
115void *xmon_stdout;
116void *xmon_stderr;
117
118void
119xmon_init(void)
120{
121}
122
123int
124xmon_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
133int
134xmon_putchar(int c)
135{
136 return xmon_putc(c, xmon_stdout);
137}
138
139int
140xmon_fputs(char *str, void *f)
141{
142 int n = strlen(str);
143
144 return xmon_write(f, str, n) == n? 0: -1;
145}
146
147int
148xmon_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
163static char line[256];
164static char *lineptr;
165static int lineleft;
166
167#if 0
168int 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
195int
196xmon_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
247char *
248xmon_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
268void
269prom_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
283void
284prom_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
24extern int xmon_write(void *, void *, int); 25extern int xmon_write(void *, void *, int);
25 26
26void 27void xmon_vfprintf(void *f, const char *fmt, va_list ap)
27xmon_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
36void 36void xmon_printf(const char *fmt, ...)
37xmon_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}
44EXPORT_SYMBOL(xmon_printf);
45 45
46void 46void xmon_fprintf(void *f, const char *fmt, ...)
47xmon_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;
58static int termch; 64static int termch;
59static char tmpstr[128]; 65static char tmpstr[128];
60 66
61#define JMP_BUF_LEN (184/sizeof(long)) 67#define JMP_BUF_LEN 23
62static long bus_error_jmp[JMP_BUF_LEN]; 68static long bus_error_jmp[JMP_BUF_LEN];
63static int catch_memory_errors; 69static int catch_memory_errors;
64static long *xmon_fault_jmp[NR_CPUS]; 70static long *xmon_fault_jmp[NR_CPUS];
@@ -130,23 +136,36 @@ static void cacheflush(void);
130static int cpu_cmd(void); 136static int cpu_cmd(void);
131static void csum(void); 137static void csum(void);
132static void bootcmds(void); 138static void bootcmds(void);
139static void proccall(void);
133void dump_segments(void); 140void dump_segments(void);
134static void symbol_lookup(void); 141static void symbol_lookup(void);
135static void xmon_print_symbol(unsigned long address, const char *mid, 142static void xmon_print_symbol(unsigned long address, const char *mid,
136 const char *after); 143 const char *after);
137static const char *getvecname(unsigned long vec); 144static const char *getvecname(unsigned long vec);
138 145
139static void debug_trace(void);
140
141extern int print_insn_powerpc(unsigned long, unsigned long, int); 146extern int print_insn_powerpc(unsigned long, unsigned long, int);
142extern void printf(const char *fmt, ...); 147extern void printf(const char *fmt, ...);
143extern void xmon_vfprintf(void *f, const char *fmt, va_list ap); 148extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
144extern int xmon_putc(int c, void *f); 149extern int xmon_putc(int c, void *f);
145extern int putchar(int ch); 150extern int putchar(int ch);
151
152extern void xmon_enter(void);
153extern void xmon_leave(void);
154
146extern int xmon_read_poll(void); 155extern int xmon_read_poll(void);
147extern int setjmp(long *); 156extern long setjmp(long *);
148extern void longjmp(long *, int); 157extern void longjmp(long *, long);
149extern unsigned long _ASR; 158extern 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
204static struct pt_regs *xmon_regs; 227static struct pt_regs *xmon_regs;
205 228
206extern inline void sync(void) 229static 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). 234static 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 239static 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) 244static 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(&regs);
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" (&regs));
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 = &regs; 519 excp = &regs;
547 } 520 }
548 return xmon_core(excp, 0); 521 return xmon_core(excp, 0);
549} 522}
523EXPORT_SYMBOL(xmon);
524
525irqreturn_t
526xmon_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
551int xmon_bpt(struct pt_regs *regs) 536int 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
1232static int xmon_depth_to_print = 64; 1218static 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
1234static void xmon_show_stack(unsigned long sp, unsigned long lr, 1232static 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, &regs, sizeof(regs)) 1295 if (mread(sp + REGS_OFFSET, &regs, 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
1384void prregs(struct pt_regs *fp) 1384void 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 = &regs; 1404 fp = &regs;
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
1425void cacheflush(void) 1439void cacheflush(void)
@@ -1519,8 +1533,7 @@ static unsigned long regno;
1519extern char exc_prolog; 1533extern char exc_prolog;
1520extern char dec_exc; 1534extern char dec_exc;
1521 1535
1522void 1536void super_regs(void)
1523super_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
1669static int fault_type; 1679static int fault_type;
1680static int fault_except;
1670static char *fault_chars[] = { "--", "**", "##" }; 1681static char *fault_chars[] = { "--", "**", "##" };
1671 1682
1672static int 1683static int handle_fault(struct pt_regs *regs)
1673handle_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
2166void 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 */
2156int 2203int
2157skipbl(void) 2204skipbl(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
2283int 2335int hexdigit(int c)
2284hexdigit(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
2402static 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
2451static void dump_slb(void) 2454static 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
2490void 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
2500void 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
2487void xmon_init(int enable) 2511void 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
2508void 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/
89core-y += arch/powerpc/sysdev/ 89core-y += arch/powerpc/sysdev/
90core-y += arch/powerpc/platforms/ 90core-y += arch/powerpc/platforms/
91core-y += arch/powerpc/lib/ 91core-y += arch/powerpc/lib/
92core-$(CONFIG_XMON) += arch/ppc64/xmon/ 92core-$(CONFIG_XMON) += arch/powerpc/xmon/
93drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 93drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
94 94
95boot := arch/ppc64/boot 95boot := 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
3EXTRA_CFLAGS += -mno-minimal-toc
4
5obj-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
471: 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
5struct pt_regs; 5struct pt_regs;
6 6
7extern void xmon(struct pt_regs *excp); 7extern int xmon(struct pt_regs *excp);
8extern void xmon_printf(const char *fmt, ...); 8extern void xmon_printf(const char *fmt, ...);
9extern void xmon_init(int); 9extern void xmon_init(int);
10 10