Commit fca5dcd4835ed09bb1a48a355344aff7a25c76e0

Authored by Paul Mackerras
1 parent 3825ac0ee6

powerpc: Simplify and clean up the xmon terminal I/O

This factors out the common bits of arch/powerpc/xmon/start_*.c into
a new nonstdio.c, and removes some stuff that was supposed to make
xmon's I/O routines somewhat stdio-like but was never used.

It also makes the parsing of the xmon= command line option common,
so that ppc32 can now use xmon={off,on,early} also.

Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 12 changed files with 236 additions and 729 deletions Inline Diff

arch/powerpc/kernel/setup-common.c
1 /* 1 /*
2 * Common boot and setup code for both 32-bit and 64-bit. 2 * Common boot and setup code for both 32-bit and 64-bit.
3 * Extracted from arch/powerpc/kernel/setup_64.c. 3 * Extracted from arch/powerpc/kernel/setup_64.c.
4 * 4 *
5 * Copyright (C) 2001 PPC64 Team, IBM Corp 5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 #include <linux/config.h> 12 #include <linux/config.h>
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/string.h> 14 #include <linux/string.h>
15 #include <linux/sched.h> 15 #include <linux/sched.h>
16 #include <linux/init.h> 16 #include <linux/init.h>
17 #include <linux/kernel.h> 17 #include <linux/kernel.h>
18 #include <linux/reboot.h> 18 #include <linux/reboot.h>
19 #include <linux/delay.h> 19 #include <linux/delay.h>
20 #include <linux/initrd.h> 20 #include <linux/initrd.h>
21 #include <linux/ide.h> 21 #include <linux/ide.h>
22 #include <linux/seq_file.h> 22 #include <linux/seq_file.h>
23 #include <linux/ioport.h> 23 #include <linux/ioport.h>
24 #include <linux/console.h> 24 #include <linux/console.h>
25 #include <linux/utsname.h> 25 #include <linux/utsname.h>
26 #include <linux/tty.h> 26 #include <linux/tty.h>
27 #include <linux/root_dev.h> 27 #include <linux/root_dev.h>
28 #include <linux/notifier.h> 28 #include <linux/notifier.h>
29 #include <linux/cpu.h> 29 #include <linux/cpu.h>
30 #include <linux/unistd.h> 30 #include <linux/unistd.h>
31 #include <linux/serial.h> 31 #include <linux/serial.h>
32 #include <linux/serial_8250.h> 32 #include <linux/serial_8250.h>
33 #include <asm/io.h> 33 #include <asm/io.h>
34 #include <asm/prom.h> 34 #include <asm/prom.h>
35 #include <asm/processor.h> 35 #include <asm/processor.h>
36 #include <asm/pgtable.h> 36 #include <asm/pgtable.h>
37 #include <asm/smp.h> 37 #include <asm/smp.h>
38 #include <asm/elf.h> 38 #include <asm/elf.h>
39 #include <asm/machdep.h> 39 #include <asm/machdep.h>
40 #include <asm/time.h> 40 #include <asm/time.h>
41 #include <asm/cputable.h> 41 #include <asm/cputable.h>
42 #include <asm/sections.h> 42 #include <asm/sections.h>
43 #include <asm/btext.h> 43 #include <asm/btext.h>
44 #include <asm/nvram.h> 44 #include <asm/nvram.h>
45 #include <asm/setup.h> 45 #include <asm/setup.h>
46 #include <asm/system.h> 46 #include <asm/system.h>
47 #include <asm/rtas.h> 47 #include <asm/rtas.h>
48 #include <asm/iommu.h> 48 #include <asm/iommu.h>
49 #include <asm/serial.h> 49 #include <asm/serial.h>
50 #include <asm/cache.h> 50 #include <asm/cache.h>
51 #include <asm/page.h> 51 #include <asm/page.h>
52 #include <asm/mmu.h> 52 #include <asm/mmu.h>
53 #include <asm/lmb.h> 53 #include <asm/lmb.h>
54 #include <asm/xmon.h>
54 55
55 #undef DEBUG 56 #undef DEBUG
56 57
57 #ifdef DEBUG 58 #ifdef DEBUG
58 #define DBG(fmt...) udbg_printf(fmt) 59 #define DBG(fmt...) udbg_printf(fmt)
59 #else 60 #else
60 #define DBG(fmt...) 61 #define DBG(fmt...)
61 #endif 62 #endif
62 63
63 /* 64 /*
64 * This still seems to be needed... -- paulus 65 * This still seems to be needed... -- paulus
65 */ 66 */
66 struct screen_info screen_info = { 67 struct screen_info screen_info = {
67 .orig_x = 0, 68 .orig_x = 0,
68 .orig_y = 25, 69 .orig_y = 25,
69 .orig_video_cols = 80, 70 .orig_video_cols = 80,
70 .orig_video_lines = 25, 71 .orig_video_lines = 25,
71 .orig_video_isVGA = 1, 72 .orig_video_isVGA = 1,
72 .orig_video_points = 16 73 .orig_video_points = 16
73 }; 74 };
74 75
75 #ifdef __DO_IRQ_CANON 76 #ifdef __DO_IRQ_CANON
76 /* XXX should go elsewhere eventually */ 77 /* XXX should go elsewhere eventually */
77 int ppc_do_canonicalize_irqs; 78 int ppc_do_canonicalize_irqs;
78 EXPORT_SYMBOL(ppc_do_canonicalize_irqs); 79 EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
79 #endif 80 #endif
80 81
81 /* also used by kexec */ 82 /* also used by kexec */
82 void machine_shutdown(void) 83 void machine_shutdown(void)
83 { 84 {
84 if (ppc_md.nvram_sync) 85 if (ppc_md.nvram_sync)
85 ppc_md.nvram_sync(); 86 ppc_md.nvram_sync();
86 } 87 }
87 88
88 void machine_restart(char *cmd) 89 void machine_restart(char *cmd)
89 { 90 {
90 machine_shutdown(); 91 machine_shutdown();
91 ppc_md.restart(cmd); 92 ppc_md.restart(cmd);
92 #ifdef CONFIG_SMP 93 #ifdef CONFIG_SMP
93 smp_send_stop(); 94 smp_send_stop();
94 #endif 95 #endif
95 printk(KERN_EMERG "System Halted, OK to turn off power\n"); 96 printk(KERN_EMERG "System Halted, OK to turn off power\n");
96 local_irq_disable(); 97 local_irq_disable();
97 while (1) ; 98 while (1) ;
98 } 99 }
99 100
100 void machine_power_off(void) 101 void machine_power_off(void)
101 { 102 {
102 machine_shutdown(); 103 machine_shutdown();
103 ppc_md.power_off(); 104 ppc_md.power_off();
104 #ifdef CONFIG_SMP 105 #ifdef CONFIG_SMP
105 smp_send_stop(); 106 smp_send_stop();
106 #endif 107 #endif
107 printk(KERN_EMERG "System Halted, OK to turn off power\n"); 108 printk(KERN_EMERG "System Halted, OK to turn off power\n");
108 local_irq_disable(); 109 local_irq_disable();
109 while (1) ; 110 while (1) ;
110 } 111 }
111 /* Used by the G5 thermal driver */ 112 /* Used by the G5 thermal driver */
112 EXPORT_SYMBOL_GPL(machine_power_off); 113 EXPORT_SYMBOL_GPL(machine_power_off);
113 114
114 void (*pm_power_off)(void) = machine_power_off; 115 void (*pm_power_off)(void) = machine_power_off;
115 EXPORT_SYMBOL_GPL(pm_power_off); 116 EXPORT_SYMBOL_GPL(pm_power_off);
116 117
117 void machine_halt(void) 118 void machine_halt(void)
118 { 119 {
119 machine_shutdown(); 120 machine_shutdown();
120 ppc_md.halt(); 121 ppc_md.halt();
121 #ifdef CONFIG_SMP 122 #ifdef CONFIG_SMP
122 smp_send_stop(); 123 smp_send_stop();
123 #endif 124 #endif
124 printk(KERN_EMERG "System Halted, OK to turn off power\n"); 125 printk(KERN_EMERG "System Halted, OK to turn off power\n");
125 local_irq_disable(); 126 local_irq_disable();
126 while (1) ; 127 while (1) ;
127 } 128 }
128 129
129 130
130 #ifdef CONFIG_TAU 131 #ifdef CONFIG_TAU
131 extern u32 cpu_temp(unsigned long cpu); 132 extern u32 cpu_temp(unsigned long cpu);
132 extern u32 cpu_temp_both(unsigned long cpu); 133 extern u32 cpu_temp_both(unsigned long cpu);
133 #endif /* CONFIG_TAU */ 134 #endif /* CONFIG_TAU */
134 135
135 #ifdef CONFIG_SMP 136 #ifdef CONFIG_SMP
136 DEFINE_PER_CPU(unsigned int, pvr); 137 DEFINE_PER_CPU(unsigned int, pvr);
137 #endif 138 #endif
138 139
139 static int show_cpuinfo(struct seq_file *m, void *v) 140 static int show_cpuinfo(struct seq_file *m, void *v)
140 { 141 {
141 unsigned long cpu_id = (unsigned long)v - 1; 142 unsigned long cpu_id = (unsigned long)v - 1;
142 unsigned int pvr; 143 unsigned int pvr;
143 unsigned short maj; 144 unsigned short maj;
144 unsigned short min; 145 unsigned short min;
145 146
146 if (cpu_id == NR_CPUS) { 147 if (cpu_id == NR_CPUS) {
147 #if defined(CONFIG_SMP) && defined(CONFIG_PPC32) 148 #if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
148 unsigned long bogosum = 0; 149 unsigned long bogosum = 0;
149 int i; 150 int i;
150 for (i = 0; i < NR_CPUS; ++i) 151 for (i = 0; i < NR_CPUS; ++i)
151 if (cpu_online(i)) 152 if (cpu_online(i))
152 bogosum += loops_per_jiffy; 153 bogosum += loops_per_jiffy;
153 seq_printf(m, "total bogomips\t: %lu.%02lu\n", 154 seq_printf(m, "total bogomips\t: %lu.%02lu\n",
154 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); 155 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
155 #endif /* CONFIG_SMP && CONFIG_PPC32 */ 156 #endif /* CONFIG_SMP && CONFIG_PPC32 */
156 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); 157 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
157 158
158 if (ppc_md.show_cpuinfo != NULL) 159 if (ppc_md.show_cpuinfo != NULL)
159 ppc_md.show_cpuinfo(m); 160 ppc_md.show_cpuinfo(m);
160 161
161 return 0; 162 return 0;
162 } 163 }
163 164
164 /* We only show online cpus: disable preempt (overzealous, I 165 /* We only show online cpus: disable preempt (overzealous, I
165 * knew) to prevent cpu going down. */ 166 * knew) to prevent cpu going down. */
166 preempt_disable(); 167 preempt_disable();
167 if (!cpu_online(cpu_id)) { 168 if (!cpu_online(cpu_id)) {
168 preempt_enable(); 169 preempt_enable();
169 return 0; 170 return 0;
170 } 171 }
171 172
172 #ifdef CONFIG_SMP 173 #ifdef CONFIG_SMP
173 pvr = per_cpu(pvr, cpu_id); 174 pvr = per_cpu(pvr, cpu_id);
174 #else 175 #else
175 pvr = mfspr(SPRN_PVR); 176 pvr = mfspr(SPRN_PVR);
176 #endif 177 #endif
177 maj = (pvr >> 8) & 0xFF; 178 maj = (pvr >> 8) & 0xFF;
178 min = pvr & 0xFF; 179 min = pvr & 0xFF;
179 180
180 seq_printf(m, "processor\t: %lu\n", cpu_id); 181 seq_printf(m, "processor\t: %lu\n", cpu_id);
181 seq_printf(m, "cpu\t\t: "); 182 seq_printf(m, "cpu\t\t: ");
182 183
183 if (cur_cpu_spec->pvr_mask) 184 if (cur_cpu_spec->pvr_mask)
184 seq_printf(m, "%s", cur_cpu_spec->cpu_name); 185 seq_printf(m, "%s", cur_cpu_spec->cpu_name);
185 else 186 else
186 seq_printf(m, "unknown (%08x)", pvr); 187 seq_printf(m, "unknown (%08x)", pvr);
187 188
188 #ifdef CONFIG_ALTIVEC 189 #ifdef CONFIG_ALTIVEC
189 if (cpu_has_feature(CPU_FTR_ALTIVEC)) 190 if (cpu_has_feature(CPU_FTR_ALTIVEC))
190 seq_printf(m, ", altivec supported"); 191 seq_printf(m, ", altivec supported");
191 #endif /* CONFIG_ALTIVEC */ 192 #endif /* CONFIG_ALTIVEC */
192 193
193 seq_printf(m, "\n"); 194 seq_printf(m, "\n");
194 195
195 #ifdef CONFIG_TAU 196 #ifdef CONFIG_TAU
196 if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { 197 if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
197 #ifdef CONFIG_TAU_AVERAGE 198 #ifdef CONFIG_TAU_AVERAGE
198 /* more straightforward, but potentially misleading */ 199 /* more straightforward, but potentially misleading */
199 seq_printf(m, "temperature \t: %u C (uncalibrated)\n", 200 seq_printf(m, "temperature \t: %u C (uncalibrated)\n",
200 cpu_temp(cpu_id)); 201 cpu_temp(cpu_id));
201 #else 202 #else
202 /* show the actual temp sensor range */ 203 /* show the actual temp sensor range */
203 u32 temp; 204 u32 temp;
204 temp = cpu_temp_both(cpu_id); 205 temp = cpu_temp_both(cpu_id);
205 seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", 206 seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
206 temp & 0xff, temp >> 16); 207 temp & 0xff, temp >> 16);
207 #endif 208 #endif
208 } 209 }
209 #endif /* CONFIG_TAU */ 210 #endif /* CONFIG_TAU */
210 211
211 /* 212 /*
212 * Assume here that all clock rates are the same in a 213 * Assume here that all clock rates are the same in a
213 * smp system. -- Cort 214 * smp system. -- Cort
214 */ 215 */
215 if (ppc_proc_freq) 216 if (ppc_proc_freq)
216 seq_printf(m, "clock\t\t: %lu.%06luMHz\n", 217 seq_printf(m, "clock\t\t: %lu.%06luMHz\n",
217 ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); 218 ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
218 219
219 if (ppc_md.show_percpuinfo != NULL) 220 if (ppc_md.show_percpuinfo != NULL)
220 ppc_md.show_percpuinfo(m, cpu_id); 221 ppc_md.show_percpuinfo(m, cpu_id);
221 222
222 /* If we are a Freescale core do a simple check so 223 /* If we are a Freescale core do a simple check so
223 * we dont have to keep adding cases in the future */ 224 * we dont have to keep adding cases in the future */
224 if (PVR_VER(pvr) & 0x8000) { 225 if (PVR_VER(pvr) & 0x8000) {
225 maj = PVR_MAJ(pvr); 226 maj = PVR_MAJ(pvr);
226 min = PVR_MIN(pvr); 227 min = PVR_MIN(pvr);
227 } else { 228 } else {
228 switch (PVR_VER(pvr)) { 229 switch (PVR_VER(pvr)) {
229 case 0x0020: /* 403 family */ 230 case 0x0020: /* 403 family */
230 maj = PVR_MAJ(pvr) + 1; 231 maj = PVR_MAJ(pvr) + 1;
231 min = PVR_MIN(pvr); 232 min = PVR_MIN(pvr);
232 break; 233 break;
233 case 0x1008: /* 740P/750P ?? */ 234 case 0x1008: /* 740P/750P ?? */
234 maj = ((pvr >> 8) & 0xFF) - 1; 235 maj = ((pvr >> 8) & 0xFF) - 1;
235 min = pvr & 0xFF; 236 min = pvr & 0xFF;
236 break; 237 break;
237 default: 238 default:
238 maj = (pvr >> 8) & 0xFF; 239 maj = (pvr >> 8) & 0xFF;
239 min = pvr & 0xFF; 240 min = pvr & 0xFF;
240 break; 241 break;
241 } 242 }
242 } 243 }
243 244
244 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", 245 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
245 maj, min, PVR_VER(pvr), PVR_REV(pvr)); 246 maj, min, PVR_VER(pvr), PVR_REV(pvr));
246 247
247 #ifdef CONFIG_PPC32 248 #ifdef CONFIG_PPC32
248 seq_printf(m, "bogomips\t: %lu.%02lu\n", 249 seq_printf(m, "bogomips\t: %lu.%02lu\n",
249 loops_per_jiffy / (500000/HZ), 250 loops_per_jiffy / (500000/HZ),
250 (loops_per_jiffy / (5000/HZ)) % 100); 251 (loops_per_jiffy / (5000/HZ)) % 100);
251 #endif 252 #endif
252 253
253 #ifdef CONFIG_SMP 254 #ifdef CONFIG_SMP
254 seq_printf(m, "\n"); 255 seq_printf(m, "\n");
255 #endif 256 #endif
256 257
257 preempt_enable(); 258 preempt_enable();
258 return 0; 259 return 0;
259 } 260 }
260 261
261 static void *c_start(struct seq_file *m, loff_t *pos) 262 static void *c_start(struct seq_file *m, loff_t *pos)
262 { 263 {
263 unsigned long i = *pos; 264 unsigned long i = *pos;
264 265
265 return i <= NR_CPUS ? (void *)(i + 1) : NULL; 266 return i <= NR_CPUS ? (void *)(i + 1) : NULL;
266 } 267 }
267 268
268 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 269 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
269 { 270 {
270 ++*pos; 271 ++*pos;
271 return c_start(m, pos); 272 return c_start(m, pos);
272 } 273 }
273 274
274 static void c_stop(struct seq_file *m, void *v) 275 static void c_stop(struct seq_file *m, void *v)
275 { 276 {
276 } 277 }
277 278
278 struct seq_operations cpuinfo_op = { 279 struct seq_operations cpuinfo_op = {
279 .start =c_start, 280 .start =c_start,
280 .next = c_next, 281 .next = c_next,
281 .stop = c_stop, 282 .stop = c_stop,
282 .show = show_cpuinfo, 283 .show = show_cpuinfo,
283 }; 284 };
284 285
285 #ifdef CONFIG_PPC_MULTIPLATFORM 286 #ifdef CONFIG_PPC_MULTIPLATFORM
286 static int __init set_preferred_console(void) 287 static int __init set_preferred_console(void)
287 { 288 {
288 struct device_node *prom_stdout = NULL; 289 struct device_node *prom_stdout = NULL;
289 char *name; 290 char *name;
290 u32 *spd; 291 u32 *spd;
291 int offset = 0; 292 int offset = 0;
292 293
293 DBG(" -> set_preferred_console()\n"); 294 DBG(" -> set_preferred_console()\n");
294 295
295 /* The user has requested a console so this is already set up. */ 296 /* The user has requested a console so this is already set up. */
296 if (strstr(saved_command_line, "console=")) { 297 if (strstr(saved_command_line, "console=")) {
297 DBG(" console was specified !\n"); 298 DBG(" console was specified !\n");
298 return -EBUSY; 299 return -EBUSY;
299 } 300 }
300 301
301 if (!of_chosen) { 302 if (!of_chosen) {
302 DBG(" of_chosen is NULL !\n"); 303 DBG(" of_chosen is NULL !\n");
303 return -ENODEV; 304 return -ENODEV;
304 } 305 }
305 /* We are getting a weird phandle from OF ... */ 306 /* We are getting a weird phandle from OF ... */
306 /* ... So use the full path instead */ 307 /* ... So use the full path instead */
307 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); 308 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
308 if (name == NULL) { 309 if (name == NULL) {
309 DBG(" no linux,stdout-path !\n"); 310 DBG(" no linux,stdout-path !\n");
310 return -ENODEV; 311 return -ENODEV;
311 } 312 }
312 prom_stdout = of_find_node_by_path(name); 313 prom_stdout = of_find_node_by_path(name);
313 if (!prom_stdout) { 314 if (!prom_stdout) {
314 DBG(" can't find stdout package %s !\n", name); 315 DBG(" can't find stdout package %s !\n", name);
315 return -ENODEV; 316 return -ENODEV;
316 } 317 }
317 DBG("stdout is %s\n", prom_stdout->full_name); 318 DBG("stdout is %s\n", prom_stdout->full_name);
318 319
319 name = (char *)get_property(prom_stdout, "name", NULL); 320 name = (char *)get_property(prom_stdout, "name", NULL);
320 if (!name) { 321 if (!name) {
321 DBG(" stdout package has no name !\n"); 322 DBG(" stdout package has no name !\n");
322 goto not_found; 323 goto not_found;
323 } 324 }
324 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); 325 spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
325 326
326 if (0) 327 if (0)
327 ; 328 ;
328 #ifdef CONFIG_SERIAL_8250_CONSOLE 329 #ifdef CONFIG_SERIAL_8250_CONSOLE
329 else if (strcmp(name, "serial") == 0) { 330 else if (strcmp(name, "serial") == 0) {
330 int i; 331 int i;
331 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); 332 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
332 if (i > 8) { 333 if (i > 8) {
333 switch (reg[1]) { 334 switch (reg[1]) {
334 case 0x3f8: 335 case 0x3f8:
335 offset = 0; 336 offset = 0;
336 break; 337 break;
337 case 0x2f8: 338 case 0x2f8:
338 offset = 1; 339 offset = 1;
339 break; 340 break;
340 case 0x898: 341 case 0x898:
341 offset = 2; 342 offset = 2;
342 break; 343 break;
343 case 0x890: 344 case 0x890:
344 offset = 3; 345 offset = 3;
345 break; 346 break;
346 default: 347 default:
347 /* We dont recognise the serial port */ 348 /* We dont recognise the serial port */
348 goto not_found; 349 goto not_found;
349 } 350 }
350 } 351 }
351 } 352 }
352 #endif /* CONFIG_SERIAL_8250_CONSOLE */ 353 #endif /* CONFIG_SERIAL_8250_CONSOLE */
353 #ifdef CONFIG_PPC_PSERIES 354 #ifdef CONFIG_PPC_PSERIES
354 else if (strcmp(name, "vty") == 0) { 355 else if (strcmp(name, "vty") == 0) {
355 u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); 356 u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
356 char *compat = (char *)get_property(prom_stdout, "compatible", NULL); 357 char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
357 358
358 if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { 359 if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
359 /* Host Virtual Serial Interface */ 360 /* Host Virtual Serial Interface */
360 switch (reg[0]) { 361 switch (reg[0]) {
361 case 0x30000000: 362 case 0x30000000:
362 offset = 0; 363 offset = 0;
363 break; 364 break;
364 case 0x30000001: 365 case 0x30000001:
365 offset = 1; 366 offset = 1;
366 break; 367 break;
367 default: 368 default:
368 goto not_found; 369 goto not_found;
369 } 370 }
370 of_node_put(prom_stdout); 371 of_node_put(prom_stdout);
371 DBG("Found hvsi console at offset %d\n", offset); 372 DBG("Found hvsi console at offset %d\n", offset);
372 return add_preferred_console("hvsi", offset, NULL); 373 return add_preferred_console("hvsi", offset, NULL);
373 } else { 374 } else {
374 /* pSeries LPAR virtual console */ 375 /* pSeries LPAR virtual console */
375 of_node_put(prom_stdout); 376 of_node_put(prom_stdout);
376 DBG("Found hvc console\n"); 377 DBG("Found hvc console\n");
377 return add_preferred_console("hvc", 0, NULL); 378 return add_preferred_console("hvc", 0, NULL);
378 } 379 }
379 } 380 }
380 #endif /* CONFIG_PPC_PSERIES */ 381 #endif /* CONFIG_PPC_PSERIES */
381 #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE 382 #ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
382 else if (strcmp(name, "ch-a") == 0) 383 else if (strcmp(name, "ch-a") == 0)
383 offset = 0; 384 offset = 0;
384 else if (strcmp(name, "ch-b") == 0) 385 else if (strcmp(name, "ch-b") == 0)
385 offset = 1; 386 offset = 1;
386 #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ 387 #endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
387 else 388 else
388 goto not_found; 389 goto not_found;
389 of_node_put(prom_stdout); 390 of_node_put(prom_stdout);
390 391
391 DBG("Found serial console at ttyS%d\n", offset); 392 DBG("Found serial console at ttyS%d\n", offset);
392 393
393 if (spd) { 394 if (spd) {
394 static char __initdata opt[16]; 395 static char __initdata opt[16];
395 sprintf(opt, "%d", *spd); 396 sprintf(opt, "%d", *spd);
396 return add_preferred_console("ttyS", offset, opt); 397 return add_preferred_console("ttyS", offset, opt);
397 } else 398 } else
398 return add_preferred_console("ttyS", offset, NULL); 399 return add_preferred_console("ttyS", offset, NULL);
399 400
400 not_found: 401 not_found:
401 DBG("No preferred console found !\n"); 402 DBG("No preferred console found !\n");
402 of_node_put(prom_stdout); 403 of_node_put(prom_stdout);
403 return -ENODEV; 404 return -ENODEV;
404 } 405 }
405 console_initcall(set_preferred_console); 406 console_initcall(set_preferred_console);
406 #endif /* CONFIG_PPC_MULTIPLATFORM */ 407 #endif /* CONFIG_PPC_MULTIPLATFORM */
407 408
408 void __init check_for_initrd(void) 409 void __init check_for_initrd(void)
409 { 410 {
410 #ifdef CONFIG_BLK_DEV_INITRD 411 #ifdef CONFIG_BLK_DEV_INITRD
411 unsigned long *prop; 412 unsigned long *prop;
412 413
413 DBG(" -> check_for_initrd()\n"); 414 DBG(" -> check_for_initrd()\n");
414 415
415 if (of_chosen) { 416 if (of_chosen) {
416 prop = (unsigned long *)get_property(of_chosen, 417 prop = (unsigned long *)get_property(of_chosen,
417 "linux,initrd-start", NULL); 418 "linux,initrd-start", NULL);
418 if (prop != NULL) { 419 if (prop != NULL) {
419 initrd_start = (unsigned long)__va(*prop); 420 initrd_start = (unsigned long)__va(*prop);
420 prop = (unsigned long *)get_property(of_chosen, 421 prop = (unsigned long *)get_property(of_chosen,
421 "linux,initrd-end", NULL); 422 "linux,initrd-end", NULL);
422 if (prop != NULL) { 423 if (prop != NULL) {
423 initrd_end = (unsigned long)__va(*prop); 424 initrd_end = (unsigned long)__va(*prop);
424 initrd_below_start_ok = 1; 425 initrd_below_start_ok = 1;
425 } else 426 } else
426 initrd_start = 0; 427 initrd_start = 0;
427 } 428 }
428 } 429 }
429 430
430 /* If we were passed an initrd, set the ROOT_DEV properly if the values 431 /* If we were passed an initrd, set the ROOT_DEV properly if the values
431 * look sensible. If not, clear initrd reference. 432 * look sensible. If not, clear initrd reference.
432 */ 433 */
433 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && 434 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
434 initrd_end > initrd_start) 435 initrd_end > initrd_start)
435 ROOT_DEV = Root_RAM0; 436 ROOT_DEV = Root_RAM0;
436 else { 437 else {
437 printk("Bogus initrd %08lx %08lx\n", initrd_start, initrd_end); 438 printk("Bogus initrd %08lx %08lx\n", initrd_start, initrd_end);
438 initrd_start = initrd_end = 0; 439 initrd_start = initrd_end = 0;
439 } 440 }
440 441
441 if (initrd_start) 442 if (initrd_start)
442 printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end); 443 printk("Found initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
443 444
444 DBG(" <- check_for_initrd()\n"); 445 DBG(" <- check_for_initrd()\n");
445 #endif /* CONFIG_BLK_DEV_INITRD */ 446 #endif /* CONFIG_BLK_DEV_INITRD */
446 } 447 }
447 448
448 #ifdef CONFIG_SMP 449 #ifdef CONFIG_SMP
449 450
450 /** 451 /**
451 * setup_cpu_maps - initialize the following cpu maps: 452 * setup_cpu_maps - initialize the following cpu maps:
452 * cpu_possible_map 453 * cpu_possible_map
453 * cpu_present_map 454 * cpu_present_map
454 * cpu_sibling_map 455 * cpu_sibling_map
455 * 456 *
456 * Having the possible map set up early allows us to restrict allocations 457 * Having the possible map set up early allows us to restrict allocations
457 * of things like irqstacks to num_possible_cpus() rather than NR_CPUS. 458 * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
458 * 459 *
459 * We do not initialize the online map here; cpus set their own bits in 460 * We do not initialize the online map here; cpus set their own bits in
460 * cpu_online_map as they come up. 461 * cpu_online_map as they come up.
461 * 462 *
462 * This function is valid only for Open Firmware systems. finish_device_tree 463 * This function is valid only for Open Firmware systems. finish_device_tree
463 * must be called before using this. 464 * must be called before using this.
464 * 465 *
465 * While we're here, we may as well set the "physical" cpu ids in the paca. 466 * While we're here, we may as well set the "physical" cpu ids in the paca.
466 */ 467 */
467 void __init smp_setup_cpu_maps(void) 468 void __init smp_setup_cpu_maps(void)
468 { 469 {
469 struct device_node *dn = NULL; 470 struct device_node *dn = NULL;
470 int cpu = 0; 471 int cpu = 0;
471 int swap_cpuid = 0; 472 int swap_cpuid = 0;
472 473
473 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 474 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
474 int *intserv; 475 int *intserv;
475 int j, len = sizeof(u32), nthreads = 1; 476 int j, len = sizeof(u32), nthreads = 1;
476 477
477 intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s", 478 intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
478 &len); 479 &len);
479 if (intserv) 480 if (intserv)
480 nthreads = len / sizeof(int); 481 nthreads = len / sizeof(int);
481 else { 482 else {
482 intserv = (int *) get_property(dn, "reg", NULL); 483 intserv = (int *) get_property(dn, "reg", NULL);
483 if (!intserv) 484 if (!intserv)
484 intserv = &cpu; /* assume logical == phys */ 485 intserv = &cpu; /* assume logical == phys */
485 } 486 }
486 487
487 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { 488 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
488 cpu_set(cpu, cpu_present_map); 489 cpu_set(cpu, cpu_present_map);
489 set_hard_smp_processor_id(cpu, intserv[j]); 490 set_hard_smp_processor_id(cpu, intserv[j]);
490 491
491 if (intserv[j] == boot_cpuid_phys) 492 if (intserv[j] == boot_cpuid_phys)
492 swap_cpuid = cpu; 493 swap_cpuid = cpu;
493 cpu_set(cpu, cpu_possible_map); 494 cpu_set(cpu, cpu_possible_map);
494 cpu++; 495 cpu++;
495 } 496 }
496 } 497 }
497 498
498 /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that 499 /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
499 * boot cpu is logical 0. 500 * boot cpu is logical 0.
500 */ 501 */
501 if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { 502 if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
502 u32 tmp; 503 u32 tmp;
503 tmp = get_hard_smp_processor_id(0); 504 tmp = get_hard_smp_processor_id(0);
504 set_hard_smp_processor_id(0, boot_cpuid_phys); 505 set_hard_smp_processor_id(0, boot_cpuid_phys);
505 set_hard_smp_processor_id(swap_cpuid, tmp); 506 set_hard_smp_processor_id(swap_cpuid, tmp);
506 } 507 }
507 508
508 #ifdef CONFIG_PPC64 509 #ifdef CONFIG_PPC64
509 /* 510 /*
510 * On pSeries LPAR, we need to know how many cpus 511 * On pSeries LPAR, we need to know how many cpus
511 * could possibly be added to this partition. 512 * could possibly be added to this partition.
512 */ 513 */
513 if (systemcfg->platform == PLATFORM_PSERIES_LPAR && 514 if (systemcfg->platform == PLATFORM_PSERIES_LPAR &&
514 (dn = of_find_node_by_path("/rtas"))) { 515 (dn = of_find_node_by_path("/rtas"))) {
515 int num_addr_cell, num_size_cell, maxcpus; 516 int num_addr_cell, num_size_cell, maxcpus;
516 unsigned int *ireg; 517 unsigned int *ireg;
517 518
518 num_addr_cell = prom_n_addr_cells(dn); 519 num_addr_cell = prom_n_addr_cells(dn);
519 num_size_cell = prom_n_size_cells(dn); 520 num_size_cell = prom_n_size_cells(dn);
520 521
521 ireg = (unsigned int *) 522 ireg = (unsigned int *)
522 get_property(dn, "ibm,lrdr-capacity", NULL); 523 get_property(dn, "ibm,lrdr-capacity", NULL);
523 524
524 if (!ireg) 525 if (!ireg)
525 goto out; 526 goto out;
526 527
527 maxcpus = ireg[num_addr_cell + num_size_cell]; 528 maxcpus = ireg[num_addr_cell + num_size_cell];
528 529
529 /* Double maxcpus for processors which have SMT capability */ 530 /* Double maxcpus for processors which have SMT capability */
530 if (cpu_has_feature(CPU_FTR_SMT)) 531 if (cpu_has_feature(CPU_FTR_SMT))
531 maxcpus *= 2; 532 maxcpus *= 2;
532 533
533 if (maxcpus > NR_CPUS) { 534 if (maxcpus > NR_CPUS) {
534 printk(KERN_WARNING 535 printk(KERN_WARNING
535 "Partition configured for %d cpus, " 536 "Partition configured for %d cpus, "
536 "operating system maximum is %d.\n", 537 "operating system maximum is %d.\n",
537 maxcpus, NR_CPUS); 538 maxcpus, NR_CPUS);
538 maxcpus = NR_CPUS; 539 maxcpus = NR_CPUS;
539 } else 540 } else
540 printk(KERN_INFO "Partition configured for %d cpus.\n", 541 printk(KERN_INFO "Partition configured for %d cpus.\n",
541 maxcpus); 542 maxcpus);
542 543
543 for (cpu = 0; cpu < maxcpus; cpu++) 544 for (cpu = 0; cpu < maxcpus; cpu++)
544 cpu_set(cpu, cpu_possible_map); 545 cpu_set(cpu, cpu_possible_map);
545 out: 546 out:
546 of_node_put(dn); 547 of_node_put(dn);
547 } 548 }
548 549
549 /* 550 /*
550 * Do the sibling map; assume only two threads per processor. 551 * Do the sibling map; assume only two threads per processor.
551 */ 552 */
552 for_each_cpu(cpu) { 553 for_each_cpu(cpu) {
553 cpu_set(cpu, cpu_sibling_map[cpu]); 554 cpu_set(cpu, cpu_sibling_map[cpu]);
554 if (cpu_has_feature(CPU_FTR_SMT)) 555 if (cpu_has_feature(CPU_FTR_SMT))
555 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); 556 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
556 } 557 }
557 558
558 systemcfg->processorCount = num_present_cpus(); 559 systemcfg->processorCount = num_present_cpus();
559 #endif /* CONFIG_PPC64 */ 560 #endif /* CONFIG_PPC64 */
560 } 561 }
561 #endif /* CONFIG_SMP */ 562 #endif /* CONFIG_SMP */
563
564 #ifdef CONFIG_XMON
565 static int __init early_xmon(char *p)
566 {
567 /* ensure xmon is enabled */
568 if (p) {
569 if (strncmp(p, "on", 2) == 0)
570 xmon_init(1);
571 if (strncmp(p, "off", 3) == 0)
572 xmon_init(0);
573 if (strncmp(p, "early", 5) != 0)
574 return 0;
575 }
576 xmon_init(1);
577 debugger(NULL);
578
579 return 0;
580 }
581 early_param("xmon", early_xmon);
582 #endif
562 583
arch/powerpc/kernel/setup_32.c
1 /* 1 /*
2 * Common prep/pmac/chrp boot and setup code. 2 * Common prep/pmac/chrp boot and setup code.
3 */ 3 */
4 4
5 #include <linux/config.h> 5 #include <linux/config.h>
6 #include <linux/module.h> 6 #include <linux/module.h>
7 #include <linux/string.h> 7 #include <linux/string.h>
8 #include <linux/sched.h> 8 #include <linux/sched.h>
9 #include <linux/init.h> 9 #include <linux/init.h>
10 #include <linux/kernel.h> 10 #include <linux/kernel.h>
11 #include <linux/reboot.h> 11 #include <linux/reboot.h>
12 #include <linux/delay.h> 12 #include <linux/delay.h>
13 #include <linux/initrd.h> 13 #include <linux/initrd.h>
14 #include <linux/ide.h> 14 #include <linux/ide.h>
15 #include <linux/tty.h> 15 #include <linux/tty.h>
16 #include <linux/bootmem.h> 16 #include <linux/bootmem.h>
17 #include <linux/seq_file.h> 17 #include <linux/seq_file.h>
18 #include <linux/root_dev.h> 18 #include <linux/root_dev.h>
19 #include <linux/cpu.h> 19 #include <linux/cpu.h>
20 #include <linux/console.h> 20 #include <linux/console.h>
21 21
22 #include <asm/residual.h> 22 #include <asm/residual.h>
23 #include <asm/io.h> 23 #include <asm/io.h>
24 #include <asm/prom.h> 24 #include <asm/prom.h>
25 #include <asm/processor.h> 25 #include <asm/processor.h>
26 #include <asm/pgtable.h> 26 #include <asm/pgtable.h>
27 #include <asm/setup.h> 27 #include <asm/setup.h>
28 #include <asm/amigappc.h> 28 #include <asm/amigappc.h>
29 #include <asm/smp.h> 29 #include <asm/smp.h>
30 #include <asm/elf.h> 30 #include <asm/elf.h>
31 #include <asm/cputable.h> 31 #include <asm/cputable.h>
32 #include <asm/bootx.h> 32 #include <asm/bootx.h>
33 #include <asm/btext.h> 33 #include <asm/btext.h>
34 #include <asm/machdep.h> 34 #include <asm/machdep.h>
35 #include <asm/uaccess.h> 35 #include <asm/uaccess.h>
36 #include <asm/system.h> 36 #include <asm/system.h>
37 #include <asm/pmac_feature.h> 37 #include <asm/pmac_feature.h>
38 #include <asm/sections.h> 38 #include <asm/sections.h>
39 #include <asm/nvram.h> 39 #include <asm/nvram.h>
40 #include <asm/xmon.h> 40 #include <asm/xmon.h>
41 #include <asm/time.h> 41 #include <asm/time.h>
42 42
43 #define DBG(fmt...) 43 #define DBG(fmt...)
44 44
45 #if defined CONFIG_KGDB 45 #if defined CONFIG_KGDB
46 #include <asm/kgdb.h> 46 #include <asm/kgdb.h>
47 #endif 47 #endif
48 48
49 extern void platform_init(void); 49 extern void platform_init(void);
50 extern void bootx_init(unsigned long r4, unsigned long phys); 50 extern void bootx_init(unsigned long r4, unsigned long phys);
51 51
52 extern void ppc6xx_idle(void); 52 extern void ppc6xx_idle(void);
53 extern void power4_idle(void); 53 extern void power4_idle(void);
54 54
55 boot_infos_t *boot_infos; 55 boot_infos_t *boot_infos;
56 struct ide_machdep_calls ppc_ide_md; 56 struct ide_machdep_calls ppc_ide_md;
57 57
58 /* XXX should go elsewhere */ 58 /* XXX should go elsewhere */
59 int __irq_offset_value; 59 int __irq_offset_value;
60 EXPORT_SYMBOL(__irq_offset_value); 60 EXPORT_SYMBOL(__irq_offset_value);
61 61
62 int boot_cpuid; 62 int boot_cpuid;
63 EXPORT_SYMBOL_GPL(boot_cpuid); 63 EXPORT_SYMBOL_GPL(boot_cpuid);
64 int boot_cpuid_phys; 64 int boot_cpuid_phys;
65 65
66 unsigned long ISA_DMA_THRESHOLD; 66 unsigned long ISA_DMA_THRESHOLD;
67 unsigned int DMA_MODE_READ; 67 unsigned int DMA_MODE_READ;
68 unsigned int DMA_MODE_WRITE; 68 unsigned int DMA_MODE_WRITE;
69 69
70 int have_of = 1; 70 int have_of = 1;
71 71
72 #ifdef CONFIG_PPC_MULTIPLATFORM 72 #ifdef CONFIG_PPC_MULTIPLATFORM
73 int _machine = 0; 73 int _machine = 0;
74 74
75 extern void prep_init(void); 75 extern void prep_init(void);
76 extern void pmac_init(void); 76 extern void pmac_init(void);
77 extern void chrp_init(void); 77 extern void chrp_init(void);
78 78
79 dev_t boot_dev; 79 dev_t boot_dev;
80 #endif /* CONFIG_PPC_MULTIPLATFORM */ 80 #endif /* CONFIG_PPC_MULTIPLATFORM */
81 81
82 #ifdef CONFIG_MAGIC_SYSRQ 82 #ifdef CONFIG_MAGIC_SYSRQ
83 unsigned long SYSRQ_KEY = 0x54; 83 unsigned long SYSRQ_KEY = 0x54;
84 #endif /* CONFIG_MAGIC_SYSRQ */ 84 #endif /* CONFIG_MAGIC_SYSRQ */
85 85
86 #ifdef CONFIG_VGA_CONSOLE 86 #ifdef CONFIG_VGA_CONSOLE
87 unsigned long vgacon_remap_base; 87 unsigned long vgacon_remap_base;
88 #endif 88 #endif
89 89
90 struct machdep_calls ppc_md; 90 struct machdep_calls ppc_md;
91 EXPORT_SYMBOL(ppc_md); 91 EXPORT_SYMBOL(ppc_md);
92 92
93 /* 93 /*
94 * These are used in binfmt_elf.c to put aux entries on the stack 94 * These are used in binfmt_elf.c to put aux entries on the stack
95 * for each elf executable being started. 95 * for each elf executable being started.
96 */ 96 */
97 int dcache_bsize; 97 int dcache_bsize;
98 int icache_bsize; 98 int icache_bsize;
99 int ucache_bsize; 99 int ucache_bsize;
100 100
101 /* 101 /*
102 * We're called here very early in the boot. We determine the machine 102 * We're called here very early in the boot. We determine the machine
103 * type and call the appropriate low-level setup functions. 103 * type and call the appropriate low-level setup functions.
104 * -- Cort <cort@fsmlabs.com> 104 * -- Cort <cort@fsmlabs.com>
105 * 105 *
106 * Note that the kernel may be running at an address which is different 106 * Note that the kernel may be running at an address which is different
107 * from the address that it was linked at, so we must use RELOC/PTRRELOC 107 * from the address that it was linked at, so we must use RELOC/PTRRELOC
108 * to access static data (including strings). -- paulus 108 * to access static data (including strings). -- paulus
109 */ 109 */
110 unsigned long __init early_init(unsigned long dt_ptr) 110 unsigned long __init early_init(unsigned long dt_ptr)
111 { 111 {
112 unsigned long offset = reloc_offset(); 112 unsigned long offset = reloc_offset();
113 113
114 /* First zero the BSS -- use memset_io, some platforms don't have 114 /* First zero the BSS -- use memset_io, some platforms don't have
115 * caches on yet */ 115 * caches on yet */
116 memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); 116 memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
117 117
118 /* 118 /*
119 * Identify the CPU type and fix up code sections 119 * Identify the CPU type and fix up code sections
120 * that depend on which cpu we have. 120 * that depend on which cpu we have.
121 */ 121 */
122 identify_cpu(offset, 0); 122 identify_cpu(offset, 0);
123 do_cpu_ftr_fixups(offset); 123 do_cpu_ftr_fixups(offset);
124 124
125 return KERNELBASE + offset; 125 return KERNELBASE + offset;
126 } 126 }
127 127
128 #ifdef CONFIG_PPC_MULTIPLATFORM 128 #ifdef CONFIG_PPC_MULTIPLATFORM
129 /* 129 /*
130 * The PPC_MULTIPLATFORM version of platform_init... 130 * The PPC_MULTIPLATFORM version of platform_init...
131 */ 131 */
132 void __init platform_init(void) 132 void __init platform_init(void)
133 { 133 {
134 /* if we didn't get any bootinfo telling us what we are... */ 134 /* if we didn't get any bootinfo telling us what we are... */
135 if (_machine == 0) { 135 if (_machine == 0) {
136 /* prep boot loader tells us if we're prep or not */ 136 /* prep boot loader tells us if we're prep or not */
137 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) 137 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
138 _machine = _MACH_prep; 138 _machine = _MACH_prep;
139 } 139 }
140 140
141 #ifdef CONFIG_PPC_PREP 141 #ifdef CONFIG_PPC_PREP
142 /* not much more to do here, if prep */ 142 /* not much more to do here, if prep */
143 if (_machine == _MACH_prep) { 143 if (_machine == _MACH_prep) {
144 prep_init(); 144 prep_init();
145 return; 145 return;
146 } 146 }
147 #endif 147 #endif
148 148
149 #ifdef CONFIG_ADB 149 #ifdef CONFIG_ADB
150 if (strstr(cmd_line, "adb_sync")) { 150 if (strstr(cmd_line, "adb_sync")) {
151 extern int __adb_probe_sync; 151 extern int __adb_probe_sync;
152 __adb_probe_sync = 1; 152 __adb_probe_sync = 1;
153 } 153 }
154 #endif /* CONFIG_ADB */ 154 #endif /* CONFIG_ADB */
155 155
156 switch (_machine) { 156 switch (_machine) {
157 #ifdef CONFIG_PPC_PMAC 157 #ifdef CONFIG_PPC_PMAC
158 case _MACH_Pmac: 158 case _MACH_Pmac:
159 pmac_init(); 159 pmac_init();
160 break; 160 break;
161 #endif 161 #endif
162 #ifdef CONFIG_PPC_CHRP 162 #ifdef CONFIG_PPC_CHRP
163 case _MACH_chrp: 163 case _MACH_chrp:
164 chrp_init(); 164 chrp_init();
165 break; 165 break;
166 #endif 166 #endif
167 } 167 }
168 } 168 }
169 #endif 169 #endif
170 170
171 /* 171 /*
172 * Find out what kind of machine we're on and save any data we need 172 * Find out what kind of machine we're on and save any data we need
173 * from the early boot process (devtree is copied on pmac by prom_init()). 173 * from the early boot process (devtree is copied on pmac by prom_init()).
174 * This is called very early on the boot process, after a minimal 174 * This is called very early on the boot process, after a minimal
175 * MMU environment has been set up but before MMU_init is called. 175 * MMU environment has been set up but before MMU_init is called.
176 */ 176 */
177 void __init machine_init(unsigned long dt_ptr, unsigned long phys) 177 void __init machine_init(unsigned long dt_ptr, unsigned long phys)
178 { 178 {
179 early_init_devtree(__va(dt_ptr)); 179 early_init_devtree(__va(dt_ptr));
180 180
181 #ifdef CONFIG_CMDLINE 181 #ifdef CONFIG_CMDLINE
182 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 182 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
183 #endif /* CONFIG_CMDLINE */ 183 #endif /* CONFIG_CMDLINE */
184 184
185 platform_init(); 185 platform_init();
186 186
187 #ifdef CONFIG_6xx 187 #ifdef CONFIG_6xx
188 ppc_md.power_save = ppc6xx_idle; 188 ppc_md.power_save = ppc6xx_idle;
189 #endif 189 #endif
190 190
191 if (ppc_md.progress) 191 if (ppc_md.progress)
192 ppc_md.progress("id mach(): done", 0x200); 192 ppc_md.progress("id mach(): done", 0x200);
193 } 193 }
194 194
195 #ifdef CONFIG_BOOKE_WDT 195 #ifdef CONFIG_BOOKE_WDT
196 /* Checks wdt=x and wdt_period=xx command-line option */ 196 /* Checks wdt=x and wdt_period=xx command-line option */
197 int __init early_parse_wdt(char *p) 197 int __init early_parse_wdt(char *p)
198 { 198 {
199 if (p && strncmp(p, "0", 1) != 0) 199 if (p && strncmp(p, "0", 1) != 0)
200 booke_wdt_enabled = 1; 200 booke_wdt_enabled = 1;
201 201
202 return 0; 202 return 0;
203 } 203 }
204 early_param("wdt", early_parse_wdt); 204 early_param("wdt", early_parse_wdt);
205 205
206 int __init early_parse_wdt_period (char *p) 206 int __init early_parse_wdt_period (char *p)
207 { 207 {
208 if (p) 208 if (p)
209 booke_wdt_period = simple_strtoul(p, NULL, 0); 209 booke_wdt_period = simple_strtoul(p, NULL, 0);
210 210
211 return 0; 211 return 0;
212 } 212 }
213 early_param("wdt_period", early_parse_wdt_period); 213 early_param("wdt_period", early_parse_wdt_period);
214 #endif /* CONFIG_BOOKE_WDT */ 214 #endif /* CONFIG_BOOKE_WDT */
215 215
216 /* Checks "l2cr=xxxx" command-line option */ 216 /* Checks "l2cr=xxxx" command-line option */
217 int __init ppc_setup_l2cr(char *str) 217 int __init ppc_setup_l2cr(char *str)
218 { 218 {
219 if (cpu_has_feature(CPU_FTR_L2CR)) { 219 if (cpu_has_feature(CPU_FTR_L2CR)) {
220 unsigned long val = simple_strtoul(str, NULL, 0); 220 unsigned long val = simple_strtoul(str, NULL, 0);
221 printk(KERN_INFO "l2cr set to %lx\n", val); 221 printk(KERN_INFO "l2cr set to %lx\n", val);
222 _set_L2CR(0); /* force invalidate by disable cache */ 222 _set_L2CR(0); /* force invalidate by disable cache */
223 _set_L2CR(val); /* and enable it */ 223 _set_L2CR(val); /* and enable it */
224 } 224 }
225 return 1; 225 return 1;
226 } 226 }
227 __setup("l2cr=", ppc_setup_l2cr); 227 __setup("l2cr=", ppc_setup_l2cr);
228 228
229 #ifdef CONFIG_GENERIC_NVRAM 229 #ifdef CONFIG_GENERIC_NVRAM
230 230
231 /* Generic nvram hooks used by drivers/char/gen_nvram.c */ 231 /* Generic nvram hooks used by drivers/char/gen_nvram.c */
232 unsigned char nvram_read_byte(int addr) 232 unsigned char nvram_read_byte(int addr)
233 { 233 {
234 if (ppc_md.nvram_read_val) 234 if (ppc_md.nvram_read_val)
235 return ppc_md.nvram_read_val(addr); 235 return ppc_md.nvram_read_val(addr);
236 return 0xff; 236 return 0xff;
237 } 237 }
238 EXPORT_SYMBOL(nvram_read_byte); 238 EXPORT_SYMBOL(nvram_read_byte);
239 239
240 void nvram_write_byte(unsigned char val, int addr) 240 void nvram_write_byte(unsigned char val, int addr)
241 { 241 {
242 if (ppc_md.nvram_write_val) 242 if (ppc_md.nvram_write_val)
243 ppc_md.nvram_write_val(addr, val); 243 ppc_md.nvram_write_val(addr, val);
244 } 244 }
245 EXPORT_SYMBOL(nvram_write_byte); 245 EXPORT_SYMBOL(nvram_write_byte);
246 246
247 void nvram_sync(void) 247 void nvram_sync(void)
248 { 248 {
249 if (ppc_md.nvram_sync) 249 if (ppc_md.nvram_sync)
250 ppc_md.nvram_sync(); 250 ppc_md.nvram_sync();
251 } 251 }
252 EXPORT_SYMBOL(nvram_sync); 252 EXPORT_SYMBOL(nvram_sync);
253 253
254 #endif /* CONFIG_NVRAM */ 254 #endif /* CONFIG_NVRAM */
255 255
256 static struct cpu cpu_devices[NR_CPUS]; 256 static struct cpu cpu_devices[NR_CPUS];
257 257
258 int __init ppc_init(void) 258 int __init ppc_init(void)
259 { 259 {
260 int i; 260 int i;
261 261
262 /* clear the progress line */ 262 /* clear the progress line */
263 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 263 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
264 264
265 /* register CPU devices */ 265 /* register CPU devices */
266 for (i = 0; i < NR_CPUS; i++) 266 for (i = 0; i < NR_CPUS; i++)
267 if (cpu_possible(i)) 267 if (cpu_possible(i))
268 register_cpu(&cpu_devices[i], i, NULL); 268 register_cpu(&cpu_devices[i], i, NULL);
269 269
270 /* call platform init */ 270 /* call platform init */
271 if (ppc_md.init != NULL) { 271 if (ppc_md.init != NULL) {
272 ppc_md.init(); 272 ppc_md.init();
273 } 273 }
274 return 0; 274 return 0;
275 } 275 }
276 276
277 arch_initcall(ppc_init); 277 arch_initcall(ppc_init);
278 278
279 /* Warning, IO base is not yet inited */ 279 /* Warning, IO base is not yet inited */
280 void __init setup_arch(char **cmdline_p) 280 void __init setup_arch(char **cmdline_p)
281 { 281 {
282 extern char *klimit; 282 extern char *klimit;
283 extern void do_init_bootmem(void); 283 extern void do_init_bootmem(void);
284 284
285 /* so udelay does something sensible, assume <= 1000 bogomips */ 285 /* so udelay does something sensible, assume <= 1000 bogomips */
286 loops_per_jiffy = 500000000 / HZ; 286 loops_per_jiffy = 500000000 / HZ;
287 287
288 unflatten_device_tree(); 288 unflatten_device_tree();
289 check_for_initrd(); 289 check_for_initrd();
290 finish_device_tree(); 290 finish_device_tree();
291 291
292 smp_setup_cpu_maps(); 292 smp_setup_cpu_maps();
293 293
294 #ifdef CONFIG_BOOTX_TEXT 294 #ifdef CONFIG_BOOTX_TEXT
295 init_boot_display(); 295 init_boot_display();
296 #endif 296 #endif
297 297
298 #ifdef CONFIG_PPC_PMAC 298 #ifdef CONFIG_PPC_PMAC
299 /* This could be called "early setup arch", it must be done 299 /* This could be called "early setup arch", it must be done
300 * now because xmon need it 300 * now because xmon need it
301 */ 301 */
302 if (_machine == _MACH_Pmac) 302 if (_machine == _MACH_Pmac)
303 pmac_feature_init(); /* New cool way */ 303 pmac_feature_init(); /* New cool way */
304 #endif 304 #endif
305 305
306 #ifdef CONFIG_XMON 306 #ifdef CONFIG_XMON_DEFAULT
307 xmon_map_scc(); 307 xmon_init(1);
308 if (strstr(cmd_line, "xmon")) { 308 #endif
309 xmon_init(1);
310 debugger(NULL);
311 }
312 #endif /* CONFIG_XMON */
313 if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
314 309
315 #if defined(CONFIG_KGDB) 310 #if defined(CONFIG_KGDB)
316 if (ppc_md.kgdb_map_scc) 311 if (ppc_md.kgdb_map_scc)
317 ppc_md.kgdb_map_scc(); 312 ppc_md.kgdb_map_scc();
318 set_debug_traps(); 313 set_debug_traps();
319 if (strstr(cmd_line, "gdb")) { 314 if (strstr(cmd_line, "gdb")) {
320 if (ppc_md.progress) 315 if (ppc_md.progress)
321 ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); 316 ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
322 printk("kgdb breakpoint activated\n"); 317 printk("kgdb breakpoint activated\n");
323 breakpoint(); 318 breakpoint();
324 } 319 }
325 #endif 320 #endif
326 321
327 /* 322 /*
328 * Set cache line size based on type of cpu as a default. 323 * Set cache line size based on type of cpu as a default.
329 * Systems with OF can look in the properties on the cpu node(s) 324 * Systems with OF can look in the properties on the cpu node(s)
330 * for a possibly more accurate value. 325 * for a possibly more accurate value.
331 */ 326 */
332 if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { 327 if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
333 dcache_bsize = cur_cpu_spec->dcache_bsize; 328 dcache_bsize = cur_cpu_spec->dcache_bsize;
334 icache_bsize = cur_cpu_spec->icache_bsize; 329 icache_bsize = cur_cpu_spec->icache_bsize;
335 ucache_bsize = 0; 330 ucache_bsize = 0;
336 } else 331 } else
337 ucache_bsize = dcache_bsize = icache_bsize 332 ucache_bsize = dcache_bsize = icache_bsize
338 = cur_cpu_spec->dcache_bsize; 333 = cur_cpu_spec->dcache_bsize;
339 334
340 /* reboot on panic */ 335 /* reboot on panic */
341 panic_timeout = 180; 336 panic_timeout = 180;
342 337
343 init_mm.start_code = PAGE_OFFSET; 338 init_mm.start_code = PAGE_OFFSET;
344 init_mm.end_code = (unsigned long) _etext; 339 init_mm.end_code = (unsigned long) _etext;
345 init_mm.end_data = (unsigned long) _edata; 340 init_mm.end_data = (unsigned long) _edata;
346 init_mm.brk = (unsigned long) klimit; 341 init_mm.brk = (unsigned long) klimit;
347 342
348 /* Save unparsed command line copy for /proc/cmdline */ 343 /* Save unparsed command line copy for /proc/cmdline */
349 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 344 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
350 *cmdline_p = cmd_line; 345 *cmdline_p = cmd_line;
351 346
352 parse_early_param(); 347 parse_early_param();
353 348
354 /* set up the bootmem stuff with available memory */ 349 /* set up the bootmem stuff with available memory */
355 do_init_bootmem(); 350 do_init_bootmem();
356 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 351 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
357 352
358 #ifdef CONFIG_PPC_OCP 353 #ifdef CONFIG_PPC_OCP
359 /* Initialize OCP device list */ 354 /* Initialize OCP device list */
360 ocp_early_init(); 355 ocp_early_init();
361 if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); 356 if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
362 #endif 357 #endif
363 358
364 #ifdef CONFIG_DUMMY_CONSOLE 359 #ifdef CONFIG_DUMMY_CONSOLE
365 conswitchp = &dummy_con; 360 conswitchp = &dummy_con;
366 #endif 361 #endif
367 362
368 ppc_md.setup_arch(); 363 ppc_md.setup_arch();
369 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 364 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
370 365
371 paging_init(); 366 paging_init();
372 367
373 /* this is for modules since _machine can be a define -- Cort */ 368 /* this is for modules since _machine can be a define -- Cort */
374 ppc_md.ppc_machine = _machine; 369 ppc_md.ppc_machine = _machine;
375 } 370 }
376 371
arch/powerpc/kernel/setup_64.c
1 /* 1 /*
2 * 2 *
3 * Common boot and setup code. 3 * Common boot and setup code.
4 * 4 *
5 * Copyright (C) 2001 PPC64 Team, IBM Corp 5 * Copyright (C) 2001 PPC64 Team, IBM Corp
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13 #undef DEBUG 13 #undef DEBUG
14 14
15 #include <linux/config.h> 15 #include <linux/config.h>
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/string.h> 17 #include <linux/string.h>
18 #include <linux/sched.h> 18 #include <linux/sched.h>
19 #include <linux/init.h> 19 #include <linux/init.h>
20 #include <linux/kernel.h> 20 #include <linux/kernel.h>
21 #include <linux/reboot.h> 21 #include <linux/reboot.h>
22 #include <linux/delay.h> 22 #include <linux/delay.h>
23 #include <linux/initrd.h> 23 #include <linux/initrd.h>
24 #include <linux/ide.h> 24 #include <linux/ide.h>
25 #include <linux/seq_file.h> 25 #include <linux/seq_file.h>
26 #include <linux/ioport.h> 26 #include <linux/ioport.h>
27 #include <linux/console.h> 27 #include <linux/console.h>
28 #include <linux/utsname.h> 28 #include <linux/utsname.h>
29 #include <linux/tty.h> 29 #include <linux/tty.h>
30 #include <linux/root_dev.h> 30 #include <linux/root_dev.h>
31 #include <linux/notifier.h> 31 #include <linux/notifier.h>
32 #include <linux/cpu.h> 32 #include <linux/cpu.h>
33 #include <linux/unistd.h> 33 #include <linux/unistd.h>
34 #include <linux/serial.h> 34 #include <linux/serial.h>
35 #include <linux/serial_8250.h> 35 #include <linux/serial_8250.h>
36 #include <asm/io.h> 36 #include <asm/io.h>
37 #include <asm/prom.h> 37 #include <asm/prom.h>
38 #include <asm/processor.h> 38 #include <asm/processor.h>
39 #include <asm/pgtable.h> 39 #include <asm/pgtable.h>
40 #include <asm/smp.h> 40 #include <asm/smp.h>
41 #include <asm/elf.h> 41 #include <asm/elf.h>
42 #include <asm/machdep.h> 42 #include <asm/machdep.h>
43 #include <asm/paca.h> 43 #include <asm/paca.h>
44 #include <asm/time.h> 44 #include <asm/time.h>
45 #include <asm/cputable.h> 45 #include <asm/cputable.h>
46 #include <asm/sections.h> 46 #include <asm/sections.h>
47 #include <asm/btext.h> 47 #include <asm/btext.h>
48 #include <asm/nvram.h> 48 #include <asm/nvram.h>
49 #include <asm/setup.h> 49 #include <asm/setup.h>
50 #include <asm/system.h> 50 #include <asm/system.h>
51 #include <asm/rtas.h> 51 #include <asm/rtas.h>
52 #include <asm/iommu.h> 52 #include <asm/iommu.h>
53 #include <asm/serial.h> 53 #include <asm/serial.h>
54 #include <asm/cache.h> 54 #include <asm/cache.h>
55 #include <asm/page.h> 55 #include <asm/page.h>
56 #include <asm/mmu.h> 56 #include <asm/mmu.h>
57 #include <asm/lmb.h> 57 #include <asm/lmb.h>
58 #include <asm/iseries/it_lp_naca.h> 58 #include <asm/iseries/it_lp_naca.h>
59 #include <asm/firmware.h> 59 #include <asm/firmware.h>
60 #include <asm/systemcfg.h> 60 #include <asm/systemcfg.h>
61 #include <asm/xmon.h> 61 #include <asm/xmon.h>
62 #include <asm/udbg.h> 62 #include <asm/udbg.h>
63 63
64 #ifdef DEBUG 64 #ifdef DEBUG
65 #define DBG(fmt...) udbg_printf(fmt) 65 #define DBG(fmt...) udbg_printf(fmt)
66 #else 66 #else
67 #define DBG(fmt...) 67 #define DBG(fmt...)
68 #endif 68 #endif
69 69
70 /* 70 /*
71 * Here are some early debugging facilities. You can enable one 71 * Here are some early debugging facilities. You can enable one
72 * but your kernel will not boot on anything else if you do so 72 * but your kernel will not boot on anything else if you do so
73 */ 73 */
74 74
75 /* This one is for use on LPAR machines that support an HVC console 75 /* This one is for use on LPAR machines that support an HVC console
76 * on vterm 0 76 * on vterm 0
77 */ 77 */
78 extern void udbg_init_debug_lpar(void); 78 extern void udbg_init_debug_lpar(void);
79 /* This one is for use on Apple G5 machines 79 /* This one is for use on Apple G5 machines
80 */ 80 */
81 extern void udbg_init_pmac_realmode(void); 81 extern void udbg_init_pmac_realmode(void);
82 /* That's RTAS panel debug */ 82 /* That's RTAS panel debug */
83 extern void call_rtas_display_status_delay(unsigned char c); 83 extern void call_rtas_display_status_delay(unsigned char c);
84 /* Here's maple real mode debug */ 84 /* Here's maple real mode debug */
85 extern void udbg_init_maple_realmode(void); 85 extern void udbg_init_maple_realmode(void);
86 86
87 #define EARLY_DEBUG_INIT() do {} while(0) 87 #define EARLY_DEBUG_INIT() do {} while(0)
88 88
89 #if 0 89 #if 0
90 #define EARLY_DEBUG_INIT() udbg_init_debug_lpar() 90 #define EARLY_DEBUG_INIT() udbg_init_debug_lpar()
91 #define EARLY_DEBUG_INIT() udbg_init_maple_realmode() 91 #define EARLY_DEBUG_INIT() udbg_init_maple_realmode()
92 #define EARLY_DEBUG_INIT() udbg_init_pmac_realmode() 92 #define EARLY_DEBUG_INIT() udbg_init_pmac_realmode()
93 #define EARLY_DEBUG_INIT() \ 93 #define EARLY_DEBUG_INIT() \
94 do { udbg_putc = call_rtas_display_status_delay; } while(0) 94 do { udbg_putc = call_rtas_display_status_delay; } while(0)
95 #endif 95 #endif
96 96
97 /* extern void *stab; */ 97 /* extern void *stab; */
98 extern unsigned long klimit; 98 extern unsigned long klimit;
99 99
100 extern void mm_init_ppc64(void); 100 extern void mm_init_ppc64(void);
101 extern void stab_initialize(unsigned long stab); 101 extern void stab_initialize(unsigned long stab);
102 extern void htab_initialize(void); 102 extern void htab_initialize(void);
103 extern void early_init_devtree(void *flat_dt); 103 extern void early_init_devtree(void *flat_dt);
104 extern void unflatten_device_tree(void); 104 extern void unflatten_device_tree(void);
105 105
106 int have_of = 1; 106 int have_of = 1;
107 int boot_cpuid = 0; 107 int boot_cpuid = 0;
108 int boot_cpuid_phys = 0; 108 int boot_cpuid_phys = 0;
109 dev_t boot_dev; 109 dev_t boot_dev;
110 u64 ppc64_pft_size; 110 u64 ppc64_pft_size;
111 111
112 struct ppc64_caches ppc64_caches; 112 struct ppc64_caches ppc64_caches;
113 EXPORT_SYMBOL_GPL(ppc64_caches); 113 EXPORT_SYMBOL_GPL(ppc64_caches);
114 114
115 /* 115 /*
116 * These are used in binfmt_elf.c to put aux entries on the stack 116 * These are used in binfmt_elf.c to put aux entries on the stack
117 * for each elf executable being started. 117 * for each elf executable being started.
118 */ 118 */
119 int dcache_bsize; 119 int dcache_bsize;
120 int icache_bsize; 120 int icache_bsize;
121 int ucache_bsize; 121 int ucache_bsize;
122 122
123 /* The main machine-dep calls structure 123 /* The main machine-dep calls structure
124 */ 124 */
125 struct machdep_calls ppc_md; 125 struct machdep_calls ppc_md;
126 EXPORT_SYMBOL(ppc_md); 126 EXPORT_SYMBOL(ppc_md);
127 127
128 #ifdef CONFIG_MAGIC_SYSRQ 128 #ifdef CONFIG_MAGIC_SYSRQ
129 unsigned long SYSRQ_KEY; 129 unsigned long SYSRQ_KEY;
130 #endif /* CONFIG_MAGIC_SYSRQ */ 130 #endif /* CONFIG_MAGIC_SYSRQ */
131 131
132 132
133 static int ppc64_panic_event(struct notifier_block *, unsigned long, void *); 133 static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
134 static struct notifier_block ppc64_panic_block = { 134 static struct notifier_block ppc64_panic_block = {
135 .notifier_call = ppc64_panic_event, 135 .notifier_call = ppc64_panic_event,
136 .priority = INT_MIN /* may not return; must be done last */ 136 .priority = INT_MIN /* may not return; must be done last */
137 }; 137 };
138 138
139 #ifdef CONFIG_SMP 139 #ifdef CONFIG_SMP
140 140
141 static int smt_enabled_cmdline; 141 static int smt_enabled_cmdline;
142 142
143 /* Look for ibm,smt-enabled OF option */ 143 /* Look for ibm,smt-enabled OF option */
144 static void check_smt_enabled(void) 144 static void check_smt_enabled(void)
145 { 145 {
146 struct device_node *dn; 146 struct device_node *dn;
147 char *smt_option; 147 char *smt_option;
148 148
149 /* Allow the command line to overrule the OF option */ 149 /* Allow the command line to overrule the OF option */
150 if (smt_enabled_cmdline) 150 if (smt_enabled_cmdline)
151 return; 151 return;
152 152
153 dn = of_find_node_by_path("/options"); 153 dn = of_find_node_by_path("/options");
154 154
155 if (dn) { 155 if (dn) {
156 smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL); 156 smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
157 157
158 if (smt_option) { 158 if (smt_option) {
159 if (!strcmp(smt_option, "on")) 159 if (!strcmp(smt_option, "on"))
160 smt_enabled_at_boot = 1; 160 smt_enabled_at_boot = 1;
161 else if (!strcmp(smt_option, "off")) 161 else if (!strcmp(smt_option, "off"))
162 smt_enabled_at_boot = 0; 162 smt_enabled_at_boot = 0;
163 } 163 }
164 } 164 }
165 } 165 }
166 166
167 /* Look for smt-enabled= cmdline option */ 167 /* Look for smt-enabled= cmdline option */
168 static int __init early_smt_enabled(char *p) 168 static int __init early_smt_enabled(char *p)
169 { 169 {
170 smt_enabled_cmdline = 1; 170 smt_enabled_cmdline = 1;
171 171
172 if (!p) 172 if (!p)
173 return 0; 173 return 0;
174 174
175 if (!strcmp(p, "on") || !strcmp(p, "1")) 175 if (!strcmp(p, "on") || !strcmp(p, "1"))
176 smt_enabled_at_boot = 1; 176 smt_enabled_at_boot = 1;
177 else if (!strcmp(p, "off") || !strcmp(p, "0")) 177 else if (!strcmp(p, "off") || !strcmp(p, "0"))
178 smt_enabled_at_boot = 0; 178 smt_enabled_at_boot = 0;
179 179
180 return 0; 180 return 0;
181 } 181 }
182 early_param("smt-enabled", early_smt_enabled); 182 early_param("smt-enabled", early_smt_enabled);
183 183
184 #else 184 #else
185 #define check_smt_enabled() 185 #define check_smt_enabled()
186 #endif /* CONFIG_SMP */ 186 #endif /* CONFIG_SMP */
187 187
188 extern struct machdep_calls pSeries_md; 188 extern struct machdep_calls pSeries_md;
189 extern struct machdep_calls pmac_md; 189 extern struct machdep_calls pmac_md;
190 extern struct machdep_calls maple_md; 190 extern struct machdep_calls maple_md;
191 extern struct machdep_calls cell_md; 191 extern struct machdep_calls cell_md;
192 extern struct machdep_calls iseries_md; 192 extern struct machdep_calls iseries_md;
193 193
194 /* Ultimately, stuff them in an elf section like initcalls... */ 194 /* Ultimately, stuff them in an elf section like initcalls... */
195 static struct machdep_calls __initdata *machines[] = { 195 static struct machdep_calls __initdata *machines[] = {
196 #ifdef CONFIG_PPC_PSERIES 196 #ifdef CONFIG_PPC_PSERIES
197 &pSeries_md, 197 &pSeries_md,
198 #endif /* CONFIG_PPC_PSERIES */ 198 #endif /* CONFIG_PPC_PSERIES */
199 #ifdef CONFIG_PPC_PMAC 199 #ifdef CONFIG_PPC_PMAC
200 &pmac_md, 200 &pmac_md,
201 #endif /* CONFIG_PPC_PMAC */ 201 #endif /* CONFIG_PPC_PMAC */
202 #ifdef CONFIG_PPC_MAPLE 202 #ifdef CONFIG_PPC_MAPLE
203 &maple_md, 203 &maple_md,
204 #endif /* CONFIG_PPC_MAPLE */ 204 #endif /* CONFIG_PPC_MAPLE */
205 #ifdef CONFIG_PPC_CELL 205 #ifdef CONFIG_PPC_CELL
206 &cell_md, 206 &cell_md,
207 #endif 207 #endif
208 #ifdef CONFIG_PPC_ISERIES 208 #ifdef CONFIG_PPC_ISERIES
209 &iseries_md, 209 &iseries_md,
210 #endif 210 #endif
211 NULL 211 NULL
212 }; 212 };
213 213
214 /* 214 /*
215 * Early initialization entry point. This is called by head.S 215 * Early initialization entry point. This is called by head.S
216 * with MMU translation disabled. We rely on the "feature" of 216 * with MMU translation disabled. We rely on the "feature" of
217 * the CPU that ignores the top 2 bits of the address in real 217 * the CPU that ignores the top 2 bits of the address in real
218 * mode so we can access kernel globals normally provided we 218 * mode so we can access kernel globals normally provided we
219 * only toy with things in the RMO region. From here, we do 219 * only toy with things in the RMO region. From here, we do
220 * some early parsing of the device-tree to setup out LMB 220 * some early parsing of the device-tree to setup out LMB
221 * data structures, and allocate & initialize the hash table 221 * data structures, and allocate & initialize the hash table
222 * and segment tables so we can start running with translation 222 * and segment tables so we can start running with translation
223 * enabled. 223 * enabled.
224 * 224 *
225 * It is this function which will call the probe() callback of 225 * It is this function which will call the probe() callback of
226 * the various platform types and copy the matching one to the 226 * the various platform types and copy the matching one to the
227 * global ppc_md structure. Your platform can eventually do 227 * global ppc_md structure. Your platform can eventually do
228 * some very early initializations from the probe() routine, but 228 * some very early initializations from the probe() routine, but
229 * this is not recommended, be very careful as, for example, the 229 * this is not recommended, be very careful as, for example, the
230 * device-tree is not accessible via normal means at this point. 230 * device-tree is not accessible via normal means at this point.
231 */ 231 */
232 232
233 void __init early_setup(unsigned long dt_ptr) 233 void __init early_setup(unsigned long dt_ptr)
234 { 234 {
235 struct paca_struct *lpaca = get_paca(); 235 struct paca_struct *lpaca = get_paca();
236 static struct machdep_calls **mach; 236 static struct machdep_calls **mach;
237 237
238 /* 238 /*
239 * Enable early debugging if any specified (see top of 239 * Enable early debugging if any specified (see top of
240 * this file) 240 * this file)
241 */ 241 */
242 EARLY_DEBUG_INIT(); 242 EARLY_DEBUG_INIT();
243 243
244 DBG(" -> early_setup()\n"); 244 DBG(" -> early_setup()\n");
245 245
246 /* 246 /*
247 * Do early initializations using the flattened device 247 * Do early initializations using the flattened device
248 * tree, like retreiving the physical memory map or 248 * tree, like retreiving the physical memory map or
249 * calculating/retreiving the hash table size 249 * calculating/retreiving the hash table size
250 */ 250 */
251 early_init_devtree(__va(dt_ptr)); 251 early_init_devtree(__va(dt_ptr));
252 252
253 /* 253 /*
254 * Iterate all ppc_md structures until we find the proper 254 * Iterate all ppc_md structures until we find the proper
255 * one for the current machine type 255 * one for the current machine type
256 */ 256 */
257 DBG("Probing machine type for platform %x...\n", 257 DBG("Probing machine type for platform %x...\n",
258 systemcfg->platform); 258 systemcfg->platform);
259 259
260 for (mach = machines; *mach; mach++) { 260 for (mach = machines; *mach; mach++) {
261 if ((*mach)->probe(systemcfg->platform)) 261 if ((*mach)->probe(systemcfg->platform))
262 break; 262 break;
263 } 263 }
264 /* What can we do if we didn't find ? */ 264 /* What can we do if we didn't find ? */
265 if (*mach == NULL) { 265 if (*mach == NULL) {
266 DBG("No suitable machine found !\n"); 266 DBG("No suitable machine found !\n");
267 for (;;); 267 for (;;);
268 } 268 }
269 ppc_md = **mach; 269 ppc_md = **mach;
270 270
271 DBG("Found, Initializing memory management...\n"); 271 DBG("Found, Initializing memory management...\n");
272 272
273 /* 273 /*
274 * Initialize the MMU Hash table and create the linear mapping 274 * Initialize the MMU Hash table and create the linear mapping
275 * of memory. Has to be done before stab/slb initialization as 275 * of memory. Has to be done before stab/slb initialization as
276 * this is currently where the page size encoding is obtained 276 * this is currently where the page size encoding is obtained
277 */ 277 */
278 htab_initialize(); 278 htab_initialize();
279 279
280 /* 280 /*
281 * Initialize stab / SLB management except on iSeries 281 * Initialize stab / SLB management except on iSeries
282 */ 282 */
283 if (!firmware_has_feature(FW_FEATURE_ISERIES)) { 283 if (!firmware_has_feature(FW_FEATURE_ISERIES)) {
284 if (cpu_has_feature(CPU_FTR_SLB)) 284 if (cpu_has_feature(CPU_FTR_SLB))
285 slb_initialize(); 285 slb_initialize();
286 else 286 else
287 stab_initialize(lpaca->stab_real); 287 stab_initialize(lpaca->stab_real);
288 } 288 }
289 289
290 DBG(" <- early_setup()\n"); 290 DBG(" <- early_setup()\n");
291 } 291 }
292 292
293 293
294 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) 294 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
295 void smp_release_cpus(void) 295 void smp_release_cpus(void)
296 { 296 {
297 extern unsigned long __secondary_hold_spinloop; 297 extern unsigned long __secondary_hold_spinloop;
298 298
299 DBG(" -> smp_release_cpus()\n"); 299 DBG(" -> smp_release_cpus()\n");
300 300
301 /* All secondary cpus are spinning on a common spinloop, release them 301 /* All secondary cpus are spinning on a common spinloop, release them
302 * all now so they can start to spin on their individual paca 302 * all now so they can start to spin on their individual paca
303 * spinloops. For non SMP kernels, the secondary cpus never get out 303 * spinloops. For non SMP kernels, the secondary cpus never get out
304 * of the common spinloop. 304 * of the common spinloop.
305 * This is useless but harmless on iSeries, secondaries are already 305 * This is useless but harmless on iSeries, secondaries are already
306 * waiting on their paca spinloops. */ 306 * waiting on their paca spinloops. */
307 307
308 __secondary_hold_spinloop = 1; 308 __secondary_hold_spinloop = 1;
309 mb(); 309 mb();
310 310
311 DBG(" <- smp_release_cpus()\n"); 311 DBG(" <- smp_release_cpus()\n");
312 } 312 }
313 #else 313 #else
314 #define smp_release_cpus() 314 #define smp_release_cpus()
315 #endif /* CONFIG_SMP || CONFIG_KEXEC */ 315 #endif /* CONFIG_SMP || CONFIG_KEXEC */
316 316
317 /* 317 /*
318 * Initialize some remaining members of the ppc64_caches and systemcfg structures 318 * Initialize some remaining members of the ppc64_caches and systemcfg structures
319 * (at least until we get rid of them completely). This is mostly some 319 * (at least until we get rid of them completely). This is mostly some
320 * cache informations about the CPU that will be used by cache flush 320 * cache informations about the CPU that will be used by cache flush
321 * routines and/or provided to userland 321 * routines and/or provided to userland
322 */ 322 */
323 static void __init initialize_cache_info(void) 323 static void __init initialize_cache_info(void)
324 { 324 {
325 struct device_node *np; 325 struct device_node *np;
326 unsigned long num_cpus = 0; 326 unsigned long num_cpus = 0;
327 327
328 DBG(" -> initialize_cache_info()\n"); 328 DBG(" -> initialize_cache_info()\n");
329 329
330 for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) { 330 for (np = NULL; (np = of_find_node_by_type(np, "cpu"));) {
331 num_cpus += 1; 331 num_cpus += 1;
332 332
333 /* We're assuming *all* of the CPUs have the same 333 /* We're assuming *all* of the CPUs have the same
334 * d-cache and i-cache sizes... -Peter 334 * d-cache and i-cache sizes... -Peter
335 */ 335 */
336 336
337 if ( num_cpus == 1 ) { 337 if ( num_cpus == 1 ) {
338 u32 *sizep, *lsizep; 338 u32 *sizep, *lsizep;
339 u32 size, lsize; 339 u32 size, lsize;
340 const char *dc, *ic; 340 const char *dc, *ic;
341 341
342 /* Then read cache informations */ 342 /* Then read cache informations */
343 if (systemcfg->platform == PLATFORM_POWERMAC) { 343 if (systemcfg->platform == PLATFORM_POWERMAC) {
344 dc = "d-cache-block-size"; 344 dc = "d-cache-block-size";
345 ic = "i-cache-block-size"; 345 ic = "i-cache-block-size";
346 } else { 346 } else {
347 dc = "d-cache-line-size"; 347 dc = "d-cache-line-size";
348 ic = "i-cache-line-size"; 348 ic = "i-cache-line-size";
349 } 349 }
350 350
351 size = 0; 351 size = 0;
352 lsize = cur_cpu_spec->dcache_bsize; 352 lsize = cur_cpu_spec->dcache_bsize;
353 sizep = (u32 *)get_property(np, "d-cache-size", NULL); 353 sizep = (u32 *)get_property(np, "d-cache-size", NULL);
354 if (sizep != NULL) 354 if (sizep != NULL)
355 size = *sizep; 355 size = *sizep;
356 lsizep = (u32 *) get_property(np, dc, NULL); 356 lsizep = (u32 *) get_property(np, dc, NULL);
357 if (lsizep != NULL) 357 if (lsizep != NULL)
358 lsize = *lsizep; 358 lsize = *lsizep;
359 if (sizep == 0 || lsizep == 0) 359 if (sizep == 0 || lsizep == 0)
360 DBG("Argh, can't find dcache properties ! " 360 DBG("Argh, can't find dcache properties ! "
361 "sizep: %p, lsizep: %p\n", sizep, lsizep); 361 "sizep: %p, lsizep: %p\n", sizep, lsizep);
362 362
363 systemcfg->dcache_size = ppc64_caches.dsize = size; 363 systemcfg->dcache_size = ppc64_caches.dsize = size;
364 systemcfg->dcache_line_size = 364 systemcfg->dcache_line_size =
365 ppc64_caches.dline_size = lsize; 365 ppc64_caches.dline_size = lsize;
366 ppc64_caches.log_dline_size = __ilog2(lsize); 366 ppc64_caches.log_dline_size = __ilog2(lsize);
367 ppc64_caches.dlines_per_page = PAGE_SIZE / lsize; 367 ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
368 368
369 size = 0; 369 size = 0;
370 lsize = cur_cpu_spec->icache_bsize; 370 lsize = cur_cpu_spec->icache_bsize;
371 sizep = (u32 *)get_property(np, "i-cache-size", NULL); 371 sizep = (u32 *)get_property(np, "i-cache-size", NULL);
372 if (sizep != NULL) 372 if (sizep != NULL)
373 size = *sizep; 373 size = *sizep;
374 lsizep = (u32 *)get_property(np, ic, NULL); 374 lsizep = (u32 *)get_property(np, ic, NULL);
375 if (lsizep != NULL) 375 if (lsizep != NULL)
376 lsize = *lsizep; 376 lsize = *lsizep;
377 if (sizep == 0 || lsizep == 0) 377 if (sizep == 0 || lsizep == 0)
378 DBG("Argh, can't find icache properties ! " 378 DBG("Argh, can't find icache properties ! "
379 "sizep: %p, lsizep: %p\n", sizep, lsizep); 379 "sizep: %p, lsizep: %p\n", sizep, lsizep);
380 380
381 systemcfg->icache_size = ppc64_caches.isize = size; 381 systemcfg->icache_size = ppc64_caches.isize = size;
382 systemcfg->icache_line_size = 382 systemcfg->icache_line_size =
383 ppc64_caches.iline_size = lsize; 383 ppc64_caches.iline_size = lsize;
384 ppc64_caches.log_iline_size = __ilog2(lsize); 384 ppc64_caches.log_iline_size = __ilog2(lsize);
385 ppc64_caches.ilines_per_page = PAGE_SIZE / lsize; 385 ppc64_caches.ilines_per_page = PAGE_SIZE / lsize;
386 } 386 }
387 } 387 }
388 388
389 /* Add an eye catcher and the systemcfg layout version number */ 389 /* Add an eye catcher and the systemcfg layout version number */
390 strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64"); 390 strcpy(systemcfg->eye_catcher, "SYSTEMCFG:PPC64");
391 systemcfg->version.major = SYSTEMCFG_MAJOR; 391 systemcfg->version.major = SYSTEMCFG_MAJOR;
392 systemcfg->version.minor = SYSTEMCFG_MINOR; 392 systemcfg->version.minor = SYSTEMCFG_MINOR;
393 systemcfg->processor = mfspr(SPRN_PVR); 393 systemcfg->processor = mfspr(SPRN_PVR);
394 394
395 DBG(" <- initialize_cache_info()\n"); 395 DBG(" <- initialize_cache_info()\n");
396 } 396 }
397 397
398 398
399 /* 399 /*
400 * Do some initial setup of the system. The parameters are those which 400 * Do some initial setup of the system. The parameters are those which
401 * were passed in from the bootloader. 401 * were passed in from the bootloader.
402 */ 402 */
403 void __init setup_system(void) 403 void __init setup_system(void)
404 { 404 {
405 DBG(" -> setup_system()\n"); 405 DBG(" -> setup_system()\n");
406 406
407 /* 407 /*
408 * Unflatten the device-tree passed by prom_init or kexec 408 * Unflatten the device-tree passed by prom_init or kexec
409 */ 409 */
410 unflatten_device_tree(); 410 unflatten_device_tree();
411 411
412 /* 412 /*
413 * Fill the ppc64_caches & systemcfg structures with informations 413 * Fill the ppc64_caches & systemcfg structures with informations
414 * retreived from the device-tree. Need to be called before 414 * retreived from the device-tree. Need to be called before
415 * finish_device_tree() since the later requires some of the 415 * finish_device_tree() since the later requires some of the
416 * informations filled up here to properly parse the interrupt 416 * informations filled up here to properly parse the interrupt
417 * tree. 417 * tree.
418 * It also sets up the cache line sizes which allows to call 418 * It also sets up the cache line sizes which allows to call
419 * routines like flush_icache_range (used by the hash init 419 * routines like flush_icache_range (used by the hash init
420 * later on). 420 * later on).
421 */ 421 */
422 initialize_cache_info(); 422 initialize_cache_info();
423 423
424 #ifdef CONFIG_PPC_RTAS 424 #ifdef CONFIG_PPC_RTAS
425 /* 425 /*
426 * Initialize RTAS if available 426 * Initialize RTAS if available
427 */ 427 */
428 rtas_initialize(); 428 rtas_initialize();
429 #endif /* CONFIG_PPC_RTAS */ 429 #endif /* CONFIG_PPC_RTAS */
430 430
431 /* 431 /*
432 * Check if we have an initrd provided via the device-tree 432 * Check if we have an initrd provided via the device-tree
433 */ 433 */
434 check_for_initrd(); 434 check_for_initrd();
435 435
436 /* 436 /*
437 * Do some platform specific early initializations, that includes 437 * Do some platform specific early initializations, that includes
438 * setting up the hash table pointers. It also sets up some interrupt-mapping 438 * setting up the hash table pointers. It also sets up some interrupt-mapping
439 * related options that will be used by finish_device_tree() 439 * related options that will be used by finish_device_tree()
440 */ 440 */
441 ppc_md.init_early(); 441 ppc_md.init_early();
442 442
443 /* 443 /*
444 * "Finish" the device-tree, that is do the actual parsing of 444 * "Finish" the device-tree, that is do the actual parsing of
445 * some of the properties like the interrupt map 445 * some of the properties like the interrupt map
446 */ 446 */
447 finish_device_tree(); 447 finish_device_tree();
448 448
449 #ifdef CONFIG_BOOTX_TEXT 449 #ifdef CONFIG_BOOTX_TEXT
450 init_boot_display(); 450 init_boot_display();
451 #endif 451 #endif
452 452
453 /* 453 /*
454 * Initialize xmon 454 * Initialize xmon
455 */ 455 */
456 #ifdef CONFIG_XMON_DEFAULT 456 #ifdef CONFIG_XMON_DEFAULT
457 xmon_init(1); 457 xmon_init(1);
458 #endif 458 #endif
459 /* 459 /*
460 * Register early console 460 * Register early console
461 */ 461 */
462 register_early_udbg_console(); 462 register_early_udbg_console();
463 463
464 /* Save unparsed command line copy for /proc/cmdline */ 464 /* Save unparsed command line copy for /proc/cmdline */
465 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 465 strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
466 466
467 parse_early_param(); 467 parse_early_param();
468 468
469 check_smt_enabled(); 469 check_smt_enabled();
470 smp_setup_cpu_maps(); 470 smp_setup_cpu_maps();
471 471
472 /* Release secondary cpus out of their spinloops at 0x60 now that 472 /* Release secondary cpus out of their spinloops at 0x60 now that
473 * we can map physical -> logical CPU ids 473 * we can map physical -> logical CPU ids
474 */ 474 */
475 smp_release_cpus(); 475 smp_release_cpus();
476 476
477 printk("Starting Linux PPC64 %s\n", system_utsname.version); 477 printk("Starting Linux PPC64 %s\n", system_utsname.version);
478 478
479 printk("-----------------------------------------------------\n"); 479 printk("-----------------------------------------------------\n");
480 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); 480 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
481 printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); 481 printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller);
482 printk("systemcfg = 0x%p\n", systemcfg); 482 printk("systemcfg = 0x%p\n", systemcfg);
483 printk("systemcfg->platform = 0x%x\n", systemcfg->platform); 483 printk("systemcfg->platform = 0x%x\n", systemcfg->platform);
484 printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); 484 printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount);
485 printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); 485 printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize);
486 printk("ppc64_caches.dcache_line_size = 0x%x\n", 486 printk("ppc64_caches.dcache_line_size = 0x%x\n",
487 ppc64_caches.dline_size); 487 ppc64_caches.dline_size);
488 printk("ppc64_caches.icache_line_size = 0x%x\n", 488 printk("ppc64_caches.icache_line_size = 0x%x\n",
489 ppc64_caches.iline_size); 489 ppc64_caches.iline_size);
490 printk("htab_address = 0x%p\n", htab_address); 490 printk("htab_address = 0x%p\n", htab_address);
491 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); 491 printk("htab_hash_mask = 0x%lx\n", htab_hash_mask);
492 printk("-----------------------------------------------------\n"); 492 printk("-----------------------------------------------------\n");
493 493
494 mm_init_ppc64(); 494 mm_init_ppc64();
495 495
496 DBG(" <- setup_system()\n"); 496 DBG(" <- setup_system()\n");
497 } 497 }
498 498
499 static int ppc64_panic_event(struct notifier_block *this, 499 static int ppc64_panic_event(struct notifier_block *this,
500 unsigned long event, void *ptr) 500 unsigned long event, void *ptr)
501 { 501 {
502 ppc_md.panic((char *)ptr); /* May not return */ 502 ppc_md.panic((char *)ptr); /* May not return */
503 return NOTIFY_DONE; 503 return NOTIFY_DONE;
504 } 504 }
505 505
506 #ifdef CONFIG_IRQSTACKS 506 #ifdef CONFIG_IRQSTACKS
507 static void __init irqstack_early_init(void) 507 static void __init irqstack_early_init(void)
508 { 508 {
509 unsigned int i; 509 unsigned int i;
510 510
511 /* 511 /*
512 * interrupt stacks must be under 256MB, we cannot afford to take 512 * interrupt stacks must be under 256MB, we cannot afford to take
513 * SLB misses on them. 513 * SLB misses on them.
514 */ 514 */
515 for_each_cpu(i) { 515 for_each_cpu(i) {
516 softirq_ctx[i] = (struct thread_info *) 516 softirq_ctx[i] = (struct thread_info *)
517 __va(lmb_alloc_base(THREAD_SIZE, 517 __va(lmb_alloc_base(THREAD_SIZE,
518 THREAD_SIZE, 0x10000000)); 518 THREAD_SIZE, 0x10000000));
519 hardirq_ctx[i] = (struct thread_info *) 519 hardirq_ctx[i] = (struct thread_info *)
520 __va(lmb_alloc_base(THREAD_SIZE, 520 __va(lmb_alloc_base(THREAD_SIZE,
521 THREAD_SIZE, 0x10000000)); 521 THREAD_SIZE, 0x10000000));
522 } 522 }
523 } 523 }
524 #else 524 #else
525 #define irqstack_early_init() 525 #define irqstack_early_init()
526 #endif 526 #endif
527 527
528 /* 528 /*
529 * Stack space used when we detect a bad kernel stack pointer, and 529 * Stack space used when we detect a bad kernel stack pointer, and
530 * early in SMP boots before relocation is enabled. 530 * early in SMP boots before relocation is enabled.
531 */ 531 */
532 static void __init emergency_stack_init(void) 532 static void __init emergency_stack_init(void)
533 { 533 {
534 unsigned long limit; 534 unsigned long limit;
535 unsigned int i; 535 unsigned int i;
536 536
537 /* 537 /*
538 * Emergency stacks must be under 256MB, we cannot afford to take 538 * Emergency stacks must be under 256MB, we cannot afford to take
539 * SLB misses on them. The ABI also requires them to be 128-byte 539 * SLB misses on them. The ABI also requires them to be 128-byte
540 * aligned. 540 * aligned.
541 * 541 *
542 * Since we use these as temporary stacks during secondary CPU 542 * Since we use these as temporary stacks during secondary CPU
543 * bringup, we need to get at them in real mode. This means they 543 * bringup, we need to get at them in real mode. This means they
544 * must also be within the RMO region. 544 * must also be within the RMO region.
545 */ 545 */
546 limit = min(0x10000000UL, lmb.rmo_size); 546 limit = min(0x10000000UL, lmb.rmo_size);
547 547
548 for_each_cpu(i) 548 for_each_cpu(i)
549 paca[i].emergency_sp = 549 paca[i].emergency_sp =
550 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE; 550 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
551 } 551 }
552 552
553 /* 553 /*
554 * Called from setup_arch to initialize the bitmap of available 554 * Called from setup_arch to initialize the bitmap of available
555 * syscalls in the systemcfg page 555 * syscalls in the systemcfg page
556 */ 556 */
557 void __init setup_syscall_map(void) 557 void __init setup_syscall_map(void)
558 { 558 {
559 unsigned int i, count64 = 0, count32 = 0; 559 unsigned int i, count64 = 0, count32 = 0;
560 extern unsigned long *sys_call_table; 560 extern unsigned long *sys_call_table;
561 extern unsigned long sys_ni_syscall; 561 extern unsigned long sys_ni_syscall;
562 562
563 563
564 for (i = 0; i < __NR_syscalls; i++) { 564 for (i = 0; i < __NR_syscalls; i++) {
565 if (sys_call_table[i*2] != sys_ni_syscall) { 565 if (sys_call_table[i*2] != sys_ni_syscall) {
566 count64++; 566 count64++;
567 systemcfg->syscall_map_64[i >> 5] |= 567 systemcfg->syscall_map_64[i >> 5] |=
568 0x80000000UL >> (i & 0x1f); 568 0x80000000UL >> (i & 0x1f);
569 } 569 }
570 if (sys_call_table[i*2+1] != sys_ni_syscall) { 570 if (sys_call_table[i*2+1] != sys_ni_syscall) {
571 count32++; 571 count32++;
572 systemcfg->syscall_map_32[i >> 5] |= 572 systemcfg->syscall_map_32[i >> 5] |=
573 0x80000000UL >> (i & 0x1f); 573 0x80000000UL >> (i & 0x1f);
574 } 574 }
575 } 575 }
576 printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n", 576 printk(KERN_INFO "Syscall map setup, %d 32-bit and %d 64-bit syscalls\n",
577 count32, count64); 577 count32, count64);
578 } 578 }
579 579
580 /* 580 /*
581 * Called into from start_kernel, after lock_kernel has been called. 581 * Called into from start_kernel, after lock_kernel has been called.
582 * Initializes bootmem, which is unsed to manage page allocation until 582 * Initializes bootmem, which is unsed to manage page allocation until
583 * mem_init is called. 583 * mem_init is called.
584 */ 584 */
585 void __init setup_arch(char **cmdline_p) 585 void __init setup_arch(char **cmdline_p)
586 { 586 {
587 extern void do_init_bootmem(void); 587 extern void do_init_bootmem(void);
588 588
589 ppc64_boot_msg(0x12, "Setup Arch"); 589 ppc64_boot_msg(0x12, "Setup Arch");
590 590
591 *cmdline_p = cmd_line; 591 *cmdline_p = cmd_line;
592 592
593 /* 593 /*
594 * Set cache line size based on type of cpu as a default. 594 * Set cache line size based on type of cpu as a default.
595 * Systems with OF can look in the properties on the cpu node(s) 595 * Systems with OF can look in the properties on the cpu node(s)
596 * for a possibly more accurate value. 596 * for a possibly more accurate value.
597 */ 597 */
598 dcache_bsize = ppc64_caches.dline_size; 598 dcache_bsize = ppc64_caches.dline_size;
599 icache_bsize = ppc64_caches.iline_size; 599 icache_bsize = ppc64_caches.iline_size;
600 600
601 /* reboot on panic */ 601 /* reboot on panic */
602 panic_timeout = 180; 602 panic_timeout = 180;
603 603
604 if (ppc_md.panic) 604 if (ppc_md.panic)
605 notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); 605 notifier_chain_register(&panic_notifier_list, &ppc64_panic_block);
606 606
607 init_mm.start_code = PAGE_OFFSET; 607 init_mm.start_code = PAGE_OFFSET;
608 init_mm.end_code = (unsigned long) _etext; 608 init_mm.end_code = (unsigned long) _etext;
609 init_mm.end_data = (unsigned long) _edata; 609 init_mm.end_data = (unsigned long) _edata;
610 init_mm.brk = klimit; 610 init_mm.brk = klimit;
611 611
612 irqstack_early_init(); 612 irqstack_early_init();
613 emergency_stack_init(); 613 emergency_stack_init();
614 614
615 stabs_alloc(); 615 stabs_alloc();
616 616
617 /* set up the bootmem stuff with available memory */ 617 /* set up the bootmem stuff with available memory */
618 do_init_bootmem(); 618 do_init_bootmem();
619 sparse_init(); 619 sparse_init();
620 620
621 /* initialize the syscall map in systemcfg */ 621 /* initialize the syscall map in systemcfg */
622 setup_syscall_map(); 622 setup_syscall_map();
623 623
624 #ifdef CONFIG_DUMMY_CONSOLE 624 #ifdef CONFIG_DUMMY_CONSOLE
625 conswitchp = &dummy_con; 625 conswitchp = &dummy_con;
626 #endif 626 #endif
627 627
628 ppc_md.setup_arch(); 628 ppc_md.setup_arch();
629 629
630 /* Use the default idle loop if the platform hasn't provided one. */ 630 /* Use the default idle loop if the platform hasn't provided one. */
631 if (NULL == ppc_md.idle_loop) { 631 if (NULL == ppc_md.idle_loop) {
632 ppc_md.idle_loop = default_idle; 632 ppc_md.idle_loop = default_idle;
633 printk(KERN_INFO "Using default idle loop\n"); 633 printk(KERN_INFO "Using default idle loop\n");
634 } 634 }
635 635
636 paging_init(); 636 paging_init();
637 ppc64_boot_msg(0x15, "Setup Done"); 637 ppc64_boot_msg(0x15, "Setup Done");
638 } 638 }
639 639
640 640
641 /* ToDo: do something useful if ppc_md is not yet setup. */ 641 /* ToDo: do something useful if ppc_md is not yet setup. */
642 #define PPC64_LINUX_FUNCTION 0x0f000000 642 #define PPC64_LINUX_FUNCTION 0x0f000000
643 #define PPC64_IPL_MESSAGE 0xc0000000 643 #define PPC64_IPL_MESSAGE 0xc0000000
644 #define PPC64_TERM_MESSAGE 0xb0000000 644 #define PPC64_TERM_MESSAGE 0xb0000000
645 645
646 static void ppc64_do_msg(unsigned int src, const char *msg) 646 static void ppc64_do_msg(unsigned int src, const char *msg)
647 { 647 {
648 if (ppc_md.progress) { 648 if (ppc_md.progress) {
649 char buf[128]; 649 char buf[128];
650 650
651 sprintf(buf, "%08X\n", src); 651 sprintf(buf, "%08X\n", src);
652 ppc_md.progress(buf, 0); 652 ppc_md.progress(buf, 0);
653 snprintf(buf, 128, "%s", msg); 653 snprintf(buf, 128, "%s", msg);
654 ppc_md.progress(buf, 0); 654 ppc_md.progress(buf, 0);
655 } 655 }
656 } 656 }
657 657
658 /* Print a boot progress message. */ 658 /* Print a boot progress message. */
659 void ppc64_boot_msg(unsigned int src, const char *msg) 659 void ppc64_boot_msg(unsigned int src, const char *msg)
660 { 660 {
661 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); 661 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
662 printk("[boot]%04x %s\n", src, msg); 662 printk("[boot]%04x %s\n", src, msg);
663 } 663 }
664 664
665 /* Print a termination message (print only -- does not stop the kernel) */ 665 /* Print a termination message (print only -- does not stop the kernel) */
666 void ppc64_terminate_msg(unsigned int src, const char *msg) 666 void ppc64_terminate_msg(unsigned int src, const char *msg)
667 { 667 {
668 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); 668 ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
669 printk("[terminate]%04x %s\n", src, msg); 669 printk("[terminate]%04x %s\n", src, msg);
670 } 670 }
671 671
672 #ifndef CONFIG_PPC_ISERIES 672 #ifndef CONFIG_PPC_ISERIES
673 /* 673 /*
674 * This function can be used by platforms to "find" legacy serial ports. 674 * This function can be used by platforms to "find" legacy serial ports.
675 * It works for "serial" nodes under an "isa" node, and will try to 675 * It works for "serial" nodes under an "isa" node, and will try to
676 * respect the "ibm,aix-loc" property if any. It works with up to 8 676 * respect the "ibm,aix-loc" property if any. It works with up to 8
677 * ports. 677 * ports.
678 */ 678 */
679 679
680 #define MAX_LEGACY_SERIAL_PORTS 8 680 #define MAX_LEGACY_SERIAL_PORTS 8
681 static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1]; 681 static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
682 static unsigned int old_serial_count; 682 static unsigned int old_serial_count;
683 683
684 void __init generic_find_legacy_serial_ports(u64 *physport, 684 void __init generic_find_legacy_serial_ports(u64 *physport,
685 unsigned int *default_speed) 685 unsigned int *default_speed)
686 { 686 {
687 struct device_node *np; 687 struct device_node *np;
688 u32 *sizeprop; 688 u32 *sizeprop;
689 689
690 struct isa_reg_property { 690 struct isa_reg_property {
691 u32 space; 691 u32 space;
692 u32 address; 692 u32 address;
693 u32 size; 693 u32 size;
694 }; 694 };
695 struct pci_reg_property { 695 struct pci_reg_property {
696 struct pci_address addr; 696 struct pci_address addr;
697 u32 size_hi; 697 u32 size_hi;
698 u32 size_lo; 698 u32 size_lo;
699 }; 699 };
700 700
701 DBG(" -> generic_find_legacy_serial_port()\n"); 701 DBG(" -> generic_find_legacy_serial_port()\n");
702 702
703 *physport = 0; 703 *physport = 0;
704 if (default_speed) 704 if (default_speed)
705 *default_speed = 0; 705 *default_speed = 0;
706 706
707 np = of_find_node_by_path("/"); 707 np = of_find_node_by_path("/");
708 if (!np) 708 if (!np)
709 return; 709 return;
710 710
711 /* First fill our array */ 711 /* First fill our array */
712 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { 712 for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
713 struct device_node *isa, *pci; 713 struct device_node *isa, *pci;
714 struct isa_reg_property *reg; 714 struct isa_reg_property *reg;
715 unsigned long phys_size, addr_size, io_base; 715 unsigned long phys_size, addr_size, io_base;
716 u32 *rangesp; 716 u32 *rangesp;
717 u32 *interrupts, *clk, *spd; 717 u32 *interrupts, *clk, *spd;
718 char *typep; 718 char *typep;
719 int index, rlen, rentsize; 719 int index, rlen, rentsize;
720 720
721 /* Ok, first check if it's under an "isa" parent */ 721 /* Ok, first check if it's under an "isa" parent */
722 isa = of_get_parent(np); 722 isa = of_get_parent(np);
723 if (!isa || strcmp(isa->name, "isa")) { 723 if (!isa || strcmp(isa->name, "isa")) {
724 DBG("%s: no isa parent found\n", np->full_name); 724 DBG("%s: no isa parent found\n", np->full_name);
725 continue; 725 continue;
726 } 726 }
727 727
728 /* Now look for an "ibm,aix-loc" property that gives us ordering 728 /* Now look for an "ibm,aix-loc" property that gives us ordering
729 * if any... 729 * if any...
730 */ 730 */
731 typep = (char *)get_property(np, "ibm,aix-loc", NULL); 731 typep = (char *)get_property(np, "ibm,aix-loc", NULL);
732 732
733 /* Get the ISA port number */ 733 /* Get the ISA port number */
734 reg = (struct isa_reg_property *)get_property(np, "reg", NULL); 734 reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
735 if (reg == NULL) 735 if (reg == NULL)
736 goto next_port; 736 goto next_port;
737 /* We assume the interrupt number isn't translated ... */ 737 /* We assume the interrupt number isn't translated ... */
738 interrupts = (u32 *)get_property(np, "interrupts", NULL); 738 interrupts = (u32 *)get_property(np, "interrupts", NULL);
739 /* get clock freq. if present */ 739 /* get clock freq. if present */
740 clk = (u32 *)get_property(np, "clock-frequency", NULL); 740 clk = (u32 *)get_property(np, "clock-frequency", NULL);
741 /* get default speed if present */ 741 /* get default speed if present */
742 spd = (u32 *)get_property(np, "current-speed", NULL); 742 spd = (u32 *)get_property(np, "current-speed", NULL);
743 /* Default to locate at end of array */ 743 /* Default to locate at end of array */
744 index = old_serial_count; /* end of the array by default */ 744 index = old_serial_count; /* end of the array by default */
745 745
746 /* If we have a location index, then use it */ 746 /* If we have a location index, then use it */
747 if (typep && *typep == 'S') { 747 if (typep && *typep == 'S') {
748 index = simple_strtol(typep+1, NULL, 0) - 1; 748 index = simple_strtol(typep+1, NULL, 0) - 1;
749 /* if index is out of range, use end of array instead */ 749 /* if index is out of range, use end of array instead */
750 if (index >= MAX_LEGACY_SERIAL_PORTS) 750 if (index >= MAX_LEGACY_SERIAL_PORTS)
751 index = old_serial_count; 751 index = old_serial_count;
752 /* if our index is still out of range, that mean that 752 /* if our index is still out of range, that mean that
753 * array is full, we could scan for a free slot but that 753 * array is full, we could scan for a free slot but that
754 * make little sense to bother, just skip the port 754 * make little sense to bother, just skip the port
755 */ 755 */
756 if (index >= MAX_LEGACY_SERIAL_PORTS) 756 if (index >= MAX_LEGACY_SERIAL_PORTS)
757 goto next_port; 757 goto next_port;
758 if (index >= old_serial_count) 758 if (index >= old_serial_count)
759 old_serial_count = index + 1; 759 old_serial_count = index + 1;
760 /* Check if there is a port who already claimed our slot */ 760 /* Check if there is a port who already claimed our slot */
761 if (serial_ports[index].iobase != 0) { 761 if (serial_ports[index].iobase != 0) {
762 /* if we still have some room, move it, else override */ 762 /* if we still have some room, move it, else override */
763 if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) { 763 if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
764 DBG("Moved legacy port %d -> %d\n", index, 764 DBG("Moved legacy port %d -> %d\n", index,
765 old_serial_count); 765 old_serial_count);
766 serial_ports[old_serial_count++] = 766 serial_ports[old_serial_count++] =
767 serial_ports[index]; 767 serial_ports[index];
768 } else { 768 } else {
769 DBG("Replacing legacy port %d\n", index); 769 DBG("Replacing legacy port %d\n", index);
770 } 770 }
771 } 771 }
772 } 772 }
773 if (index >= MAX_LEGACY_SERIAL_PORTS) 773 if (index >= MAX_LEGACY_SERIAL_PORTS)
774 goto next_port; 774 goto next_port;
775 if (index >= old_serial_count) 775 if (index >= old_serial_count)
776 old_serial_count = index + 1; 776 old_serial_count = index + 1;
777 777
778 /* Now fill the entry */ 778 /* Now fill the entry */
779 memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port)); 779 memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
780 serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16; 780 serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
781 serial_ports[index].iobase = reg->address; 781 serial_ports[index].iobase = reg->address;
782 serial_ports[index].irq = interrupts ? interrupts[0] : 0; 782 serial_ports[index].irq = interrupts ? interrupts[0] : 0;
783 serial_ports[index].flags = ASYNC_BOOT_AUTOCONF; 783 serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
784 784
785 DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", 785 DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
786 index, 786 index,
787 serial_ports[index].iobase, 787 serial_ports[index].iobase,
788 serial_ports[index].irq, 788 serial_ports[index].irq,
789 serial_ports[index].uartclk); 789 serial_ports[index].uartclk);
790 790
791 /* Get phys address of IO reg for port 1 */ 791 /* Get phys address of IO reg for port 1 */
792 if (index != 0) 792 if (index != 0)
793 goto next_port; 793 goto next_port;
794 794
795 pci = of_get_parent(isa); 795 pci = of_get_parent(isa);
796 if (!pci) { 796 if (!pci) {
797 DBG("%s: no pci parent found\n", np->full_name); 797 DBG("%s: no pci parent found\n", np->full_name);
798 goto next_port; 798 goto next_port;
799 } 799 }
800 800
801 rangesp = (u32 *)get_property(pci, "ranges", &rlen); 801 rangesp = (u32 *)get_property(pci, "ranges", &rlen);
802 if (rangesp == NULL) { 802 if (rangesp == NULL) {
803 of_node_put(pci); 803 of_node_put(pci);
804 goto next_port; 804 goto next_port;
805 } 805 }
806 rlen /= 4; 806 rlen /= 4;
807 807
808 /* we need the #size-cells of the PCI bridge node itself */ 808 /* we need the #size-cells of the PCI bridge node itself */
809 phys_size = 1; 809 phys_size = 1;
810 sizeprop = (u32 *)get_property(pci, "#size-cells", NULL); 810 sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
811 if (sizeprop != NULL) 811 if (sizeprop != NULL)
812 phys_size = *sizeprop; 812 phys_size = *sizeprop;
813 /* we need the parent #addr-cells */ 813 /* we need the parent #addr-cells */
814 addr_size = prom_n_addr_cells(pci); 814 addr_size = prom_n_addr_cells(pci);
815 rentsize = 3 + addr_size + phys_size; 815 rentsize = 3 + addr_size + phys_size;
816 io_base = 0; 816 io_base = 0;
817 for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) { 817 for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
818 if (((rangesp[0] >> 24) & 0x3) != 1) 818 if (((rangesp[0] >> 24) & 0x3) != 1)
819 continue; /* not IO space */ 819 continue; /* not IO space */
820 io_base = rangesp[3]; 820 io_base = rangesp[3];
821 if (addr_size == 2) 821 if (addr_size == 2)
822 io_base = (io_base << 32) | rangesp[4]; 822 io_base = (io_base << 32) | rangesp[4];
823 } 823 }
824 if (io_base != 0) { 824 if (io_base != 0) {
825 *physport = io_base + reg->address; 825 *physport = io_base + reg->address;
826 if (default_speed && spd) 826 if (default_speed && spd)
827 *default_speed = *spd; 827 *default_speed = *spd;
828 } 828 }
829 of_node_put(pci); 829 of_node_put(pci);
830 next_port: 830 next_port:
831 of_node_put(isa); 831 of_node_put(isa);
832 } 832 }
833 833
834 DBG(" <- generic_find_legacy_serial_port()\n"); 834 DBG(" <- generic_find_legacy_serial_port()\n");
835 } 835 }
836 836
837 static struct platform_device serial_device = { 837 static struct platform_device serial_device = {
838 .name = "serial8250", 838 .name = "serial8250",
839 .id = PLAT8250_DEV_PLATFORM, 839 .id = PLAT8250_DEV_PLATFORM,
840 .dev = { 840 .dev = {
841 .platform_data = serial_ports, 841 .platform_data = serial_ports,
842 }, 842 },
843 }; 843 };
844 844
845 static int __init serial_dev_init(void) 845 static int __init serial_dev_init(void)
846 { 846 {
847 return platform_device_register(&serial_device); 847 return platform_device_register(&serial_device);
848 } 848 }
849 arch_initcall(serial_dev_init); 849 arch_initcall(serial_dev_init);
850 850
851 #endif /* CONFIG_PPC_ISERIES */ 851 #endif /* CONFIG_PPC_ISERIES */
852 852
853 int check_legacy_ioport(unsigned long base_port) 853 int check_legacy_ioport(unsigned long base_port)
854 { 854 {
855 if (ppc_md.check_legacy_ioport == NULL) 855 if (ppc_md.check_legacy_ioport == NULL)
856 return 0; 856 return 0;
857 return ppc_md.check_legacy_ioport(base_port); 857 return ppc_md.check_legacy_ioport(base_port);
858 } 858 }
859 EXPORT_SYMBOL(check_legacy_ioport); 859 EXPORT_SYMBOL(check_legacy_ioport);
860 860
861 #ifdef CONFIG_XMON
862 static int __init early_xmon(char *p)
863 {
864 /* ensure xmon is enabled */
865 if (p) {
866 if (strncmp(p, "on", 2) == 0)
867 xmon_init(1);
868 if (strncmp(p, "off", 3) == 0)
869 xmon_init(0);
870 if (strncmp(p, "early", 5) != 0)
871 return 0;
872 }
873 xmon_init(1);
874 debugger(NULL);
875
876 return 0;
877 }
878 early_param("xmon", early_xmon);
879 #endif
880
881 void cpu_die(void) 861 void cpu_die(void)
882 { 862 {
883 if (ppc_md.cpu_die) 863 if (ppc_md.cpu_die)
884 ppc_md.cpu_die(); 864 ppc_md.cpu_die();
885 } 865 }
886 866
arch/powerpc/xmon/Makefile
1 # Makefile for xmon 1 # Makefile for xmon
2 2
3 ifdef CONFIG_PPC64 3 ifdef CONFIG_PPC64
4 EXTRA_CFLAGS += -mno-minimal-toc 4 EXTRA_CFLAGS += -mno-minimal-toc
5 endif 5 endif
6 6
7 obj-$(CONFIG_8xx) += start_8xx.o 7 obj-$(CONFIG_8xx) += start_8xx.o
8 obj-$(CONFIG_6xx) += start_32.o 8 obj-$(CONFIG_6xx) += start_32.o
9 obj-$(CONFIG_4xx) += start_32.o 9 obj-$(CONFIG_4xx) += start_32.o
10 obj-$(CONFIG_PPC64) += start_64.o 10 obj-$(CONFIG_PPC64) += start_64.o
11 obj-y += xmon.o ppc-dis.o ppc-opc.o subr_prf.o setjmp.o 11 obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
12 12
arch/powerpc/xmon/nonstdio.c
File was created 1 /*
2 * Copyright (C) 1996-2005 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 #include <linux/string.h>
10 #include <asm/time.h>
11 #include "nonstdio.h"
12
13 int xmon_putchar(int c)
14 {
15 char ch = c;
16
17 if (c == '\n')
18 xmon_putchar('\r');
19 return xmon_write(&ch, 1) == 1? c: -1;
20 }
21
22 static char line[256];
23 static char *lineptr;
24 static int lineleft;
25
26 int xmon_expect(const char *str, unsigned long timeout)
27 {
28 int c;
29 unsigned long t0;
30
31 /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
32 timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
33 t0 = get_tbl();
34 do {
35 lineptr = line;
36 for (;;) {
37 c = xmon_read_poll();
38 if (c == -1) {
39 if (get_tbl() - t0 > timeout)
40 return 0;
41 continue;
42 }
43 if (c == '\n')
44 break;
45 if (c != '\r' && lineptr < &line[sizeof(line) - 1])
46 *lineptr++ = c;
47 }
48 *lineptr = 0;
49 } while (strstr(line, str) == NULL);
50 return 1;
51 }
52
53 int xmon_getchar(void)
54 {
55 int c;
56
57 if (lineleft == 0) {
58 lineptr = line;
59 for (;;) {
60 c = xmon_readchar();
61 if (c == -1 || c == 4)
62 break;
63 if (c == '\r' || c == '\n') {
64 *lineptr++ = '\n';
65 xmon_putchar('\n');
66 break;
67 }
68 switch (c) {
69 case 0177:
70 case '\b':
71 if (lineptr > line) {
72 xmon_putchar('\b');
73 xmon_putchar(' ');
74 xmon_putchar('\b');
75 --lineptr;
76 }
77 break;
78 case 'U' & 0x1F:
79 while (lineptr > line) {
80 xmon_putchar('\b');
81 xmon_putchar(' ');
82 xmon_putchar('\b');
83 --lineptr;
84 }
85 break;
86 default:
87 if (lineptr >= &line[sizeof(line) - 1])
88 xmon_putchar('\a');
89 else {
90 xmon_putchar(c);
91 *lineptr++ = c;
92 }
93 }
94 }
95 lineleft = lineptr - line;
96 lineptr = line;
97 }
98 if (lineleft == 0)
99 return -1;
100 --lineleft;
101 return *lineptr++;
102 }
103
104 char *xmon_gets(char *str, int nb)
105 {
106 char *p;
107 int c;
108
109 for (p = str; p < str + nb - 1; ) {
110 c = xmon_getchar();
111 if (c == -1) {
112 if (p == str)
113 return NULL;
114 break;
115 }
116 *p++ = c;
117 if (c == '\n')
118 break;
119 }
120 *p = 0;
121 return str;
122 }
123
124 void xmon_printf(const char *format, ...)
125 {
126 va_list args;
127 int n;
128 static char xmon_outbuf[1024];
129
130 va_start(args, format);
131 n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
132 va_end(args);
133 xmon_write(xmon_outbuf, n);
134 }
135
arch/powerpc/xmon/nonstdio.h
1 typedef int FILE;
2 extern FILE *xmon_stdin, *xmon_stdout;
3 #define EOF (-1) 1 #define EOF (-1)
4 #define stdin xmon_stdin 2
5 #define stdout xmon_stdout
6 #define printf xmon_printf 3 #define printf xmon_printf
7 #define fprintf xmon_fprintf
8 #define fputs xmon_fputs
9 #define fgets xmon_fgets
10 #define putchar xmon_putchar 4 #define putchar xmon_putchar
11 #define getchar xmon_getchar
12 #define putc xmon_putc
13 #define getc xmon_getc
14 #define fopen(n, m) NULL
15 #define fflush(f) do {} while (0)
16 #define fclose(f) do {} while (0)
17 extern char *fgets(char *, int, void *);
18 extern void xmon_printf(const char *, ...);
19 extern void xmon_fprintf(void *, const char *, ...);
20 extern void xmon_sprintf(char *, const char *, ...);
21 5
22 #define perror(s) printf("%s: no files!\n", (s)) 6 extern int xmon_putchar(int c);
7 extern int xmon_getchar(void);
arch/powerpc/xmon/start_32.c
1 /* 1 /*
2 * Copyright (C) 1996 Paul Mackerras. 2 * Copyright (C) 1996 Paul Mackerras.
3 */ 3 */
4 #include <linux/config.h> 4 #include <linux/config.h>
5 #include <linux/string.h> 5 #include <linux/string.h>
6 #include <asm/machdep.h> 6 #include <asm/machdep.h>
7 #include <asm/io.h> 7 #include <asm/io.h>
8 #include <asm/page.h> 8 #include <asm/page.h>
9 #include <linux/adb.h> 9 #include <linux/adb.h>
10 #include <linux/pmu.h> 10 #include <linux/pmu.h>
11 #include <linux/cuda.h> 11 #include <linux/cuda.h>
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/errno.h> 13 #include <linux/errno.h>
14 #include <linux/sysrq.h>
15 #include <linux/bitops.h> 14 #include <linux/bitops.h>
16 #include <asm/xmon.h> 15 #include <asm/xmon.h>
17 #include <asm/prom.h> 16 #include <asm/prom.h>
18 #include <asm/bootx.h> 17 #include <asm/bootx.h>
19 #include <asm/machdep.h> 18 #include <asm/machdep.h>
20 #include <asm/errno.h> 19 #include <asm/errno.h>
21 #include <asm/pmac_feature.h> 20 #include <asm/pmac_feature.h>
22 #include <asm/processor.h> 21 #include <asm/processor.h>
23 #include <asm/delay.h> 22 #include <asm/delay.h>
24 #include <asm/btext.h> 23 #include <asm/btext.h>
24 #include <asm/time.h>
25 #include "nonstdio.h"
25 26
26 static volatile unsigned char __iomem *sccc, *sccd; 27 static volatile unsigned char __iomem *sccc, *sccd;
27 unsigned int TXRDY, RXRDY, DLAB; 28 unsigned int TXRDY, RXRDY, DLAB;
28 static int xmon_expect(const char *str, unsigned int timeout);
29 29
30 static int use_serial; 30 static int use_serial;
31 static int use_screen; 31 static int use_screen;
32 static int via_modem; 32 static int via_modem;
33 static int xmon_use_sccb; 33 static int xmon_use_sccb;
34 static struct device_node *channel_node; 34 static struct device_node *channel_node;
35 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) 36 void buf_access(void)
47 { 37 {
48 if (DLAB) 38 if (DLAB)
49 sccd[3] &= ~DLAB; /* reset DLAB */ 39 sccd[3] &= ~DLAB; /* reset DLAB */
50 } 40 }
51 41
52 extern int adb_init(void); 42 extern int adb_init(void);
53 43
54 #ifdef CONFIG_PPC_CHRP 44 #ifdef CONFIG_PPC_CHRP
55 /* 45 /*
56 * This looks in the "ranges" property for the primary PCI host bridge 46 * 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. 47 * 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. 48 * It is basically a cut-down version of pci_process_bridge_OF_ranges.
59 */ 49 */
60 static unsigned long chrp_find_phys_io_base(void) 50 static unsigned long chrp_find_phys_io_base(void)
61 { 51 {
62 struct device_node *node; 52 struct device_node *node;
63 unsigned int *ranges; 53 unsigned int *ranges;
64 unsigned long base = CHRP_ISA_IO_BASE; 54 unsigned long base = CHRP_ISA_IO_BASE;
65 int rlen = 0; 55 int rlen = 0;
66 int np; 56 int np;
67 57
68 node = find_devices("isa"); 58 node = find_devices("isa");
69 if (node != NULL) { 59 if (node != NULL) {
70 node = node->parent; 60 node = node->parent;
71 if (node == NULL || node->type == NULL 61 if (node == NULL || node->type == NULL
72 || strcmp(node->type, "pci") != 0) 62 || strcmp(node->type, "pci") != 0)
73 node = NULL; 63 node = NULL;
74 } 64 }
75 if (node == NULL) 65 if (node == NULL)
76 node = find_devices("pci"); 66 node = find_devices("pci");
77 if (node == NULL) 67 if (node == NULL)
78 return base; 68 return base;
79 69
80 ranges = (unsigned int *) get_property(node, "ranges", &rlen); 70 ranges = (unsigned int *) get_property(node, "ranges", &rlen);
81 np = prom_n_addr_cells(node) + 5; 71 np = prom_n_addr_cells(node) + 5;
82 while ((rlen -= np * sizeof(unsigned int)) >= 0) { 72 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
83 if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { 73 if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
84 /* I/O space starting at 0, grab the phys base */ 74 /* I/O space starting at 0, grab the phys base */
85 base = ranges[np - 3]; 75 base = ranges[np - 3];
86 break; 76 break;
87 } 77 }
88 ranges += np; 78 ranges += np;
89 } 79 }
90 return base; 80 return base;
91 } 81 }
92 #endif /* CONFIG_PPC_CHRP */ 82 #endif /* CONFIG_PPC_CHRP */
93 83
94 #ifdef CONFIG_MAGIC_SYSRQ 84 void xmon_map_scc(void)
95 static void sysrq_handle_xmon(int key, struct pt_regs *regs,
96 struct tty_struct *tty)
97 { 85 {
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 86 #ifdef CONFIG_PPC_MULTIPLATFORM
113 volatile unsigned char __iomem *base; 87 volatile unsigned char __iomem *base;
114 88
115 if (_machine == _MACH_Pmac) { 89 if (_machine == _MACH_Pmac) {
116 struct device_node *np; 90 struct device_node *np;
117 unsigned long addr; 91 unsigned long addr;
118 #ifdef CONFIG_BOOTX_TEXT 92 #ifdef CONFIG_BOOTX_TEXT
119 if (!use_screen && !use_serial 93 if (!use_screen && !use_serial
120 && !machine_is_compatible("iMac")) { 94 && !machine_is_compatible("iMac")) {
121 /* see if there is a keyboard in the device tree 95 /* see if there is a keyboard in the device tree
122 with a parent of type "adb" */ 96 with a parent of type "adb" */
123 for (np = find_devices("keyboard"); np; np = np->next) 97 for (np = find_devices("keyboard"); np; np = np->next)
124 if (np->parent && np->parent->type 98 if (np->parent && np->parent->type
125 && strcmp(np->parent->type, "adb") == 0) 99 && strcmp(np->parent->type, "adb") == 0)
126 break; 100 break;
127 101
128 /* needs to be hacked if xmon_printk is to be used 102 /* needs to be hacked if xmon_printk is to be used
129 from within find_via_pmu() */ 103 from within find_via_pmu() */
130 #ifdef CONFIG_ADB_PMU 104 #ifdef CONFIG_ADB_PMU
131 if (np != NULL && boot_text_mapped && find_via_pmu()) 105 if (np != NULL && boot_text_mapped && find_via_pmu())
132 use_screen = 1; 106 use_screen = 1;
133 #endif 107 #endif
134 #ifdef CONFIG_ADB_CUDA 108 #ifdef CONFIG_ADB_CUDA
135 if (np != NULL && boot_text_mapped && find_via_cuda()) 109 if (np != NULL && boot_text_mapped && find_via_cuda())
136 use_screen = 1; 110 use_screen = 1;
137 #endif 111 #endif
138 } 112 }
139 if (!use_screen && (np = find_devices("escc")) != NULL) { 113 if (!use_screen && (np = find_devices("escc")) != NULL) {
140 /* 114 /*
141 * look for the device node for the serial port 115 * look for the device node for the serial port
142 * we're using and see if it says it has a modem 116 * we're using and see if it says it has a modem
143 */ 117 */
144 char *name = xmon_use_sccb? "ch-b": "ch-a"; 118 char *name = xmon_use_sccb? "ch-b": "ch-a";
145 char *slots; 119 char *slots;
146 int l; 120 int l;
147 121
148 np = np->child; 122 np = np->child;
149 while (np != NULL && strcmp(np->name, name) != 0) 123 while (np != NULL && strcmp(np->name, name) != 0)
150 np = np->sibling; 124 np = np->sibling;
151 if (np != NULL) { 125 if (np != NULL) {
152 /* XXX should parse this properly */ 126 /* XXX should parse this properly */
153 channel_node = np; 127 channel_node = np;
154 slots = get_property(np, "slot-names", &l); 128 slots = get_property(np, "slot-names", &l);
155 if (slots != NULL && l >= 10 129 if (slots != NULL && l >= 10
156 && strcmp(slots+4, "Modem") == 0) 130 && strcmp(slots+4, "Modem") == 0)
157 via_modem = 1; 131 via_modem = 1;
158 } 132 }
159 } 133 }
160 btext_drawstring("xmon uses "); 134 btext_drawstring("xmon uses ");
161 if (use_screen) 135 if (use_screen)
162 btext_drawstring("screen and keyboard\n"); 136 btext_drawstring("screen and keyboard\n");
163 else { 137 else {
164 if (via_modem) 138 if (via_modem)
165 btext_drawstring("modem on "); 139 btext_drawstring("modem on ");
166 btext_drawstring(xmon_use_sccb? "printer": "modem"); 140 btext_drawstring(xmon_use_sccb? "printer": "modem");
167 btext_drawstring(" port\n"); 141 btext_drawstring(" port\n");
168 } 142 }
169 143
170 #endif /* CONFIG_BOOTX_TEXT */ 144 #endif /* CONFIG_BOOTX_TEXT */
171 145
172 #ifdef CHRP_ESCC 146 #ifdef CHRP_ESCC
173 addr = 0xc1013020; 147 addr = 0xc1013020;
174 #else 148 #else
175 addr = 0xf3013020; 149 addr = 0xf3013020;
176 #endif 150 #endif
177 TXRDY = 4; 151 TXRDY = 4;
178 RXRDY = 1; 152 RXRDY = 1;
179 153
180 np = find_devices("mac-io"); 154 np = find_devices("mac-io");
181 if (np && np->n_addrs) 155 if (np && np->n_addrs)
182 addr = np->addrs[0].address + 0x13020; 156 addr = np->addrs[0].address + 0x13020;
183 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); 157 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
184 sccc = base + (addr & ~PAGE_MASK); 158 sccc = base + (addr & ~PAGE_MASK);
185 sccd = sccc + 0x10; 159 sccd = sccc + 0x10;
186 160
187 } else { 161 } else {
188 base = (volatile unsigned char *) isa_io_base; 162 base = (volatile unsigned char *) isa_io_base;
189 163
190 #ifdef CONFIG_PPC_CHRP 164 #ifdef CONFIG_PPC_CHRP
191 if (_machine == _MACH_chrp) 165 if (_machine == _MACH_chrp)
192 base = (volatile unsigned char __iomem *) 166 base = (volatile unsigned char __iomem *)
193 ioremap(chrp_find_phys_io_base(), 0x1000); 167 ioremap(chrp_find_phys_io_base(), 0x1000);
194 #endif 168 #endif
195 169
196 sccc = base + 0x3fd; 170 sccc = base + 0x3fd;
197 sccd = base + 0x3f8; 171 sccd = base + 0x3f8;
198 if (xmon_use_sccb) { 172 if (xmon_use_sccb) {
199 sccc -= 0x100; 173 sccc -= 0x100;
200 sccd -= 0x100; 174 sccd -= 0x100;
201 } 175 }
202 TXRDY = 0x20; 176 TXRDY = 0x20;
203 RXRDY = 1; 177 RXRDY = 1;
204 DLAB = 0x80; 178 DLAB = 0x80;
205 } 179 }
206 #elif defined(CONFIG_GEMINI) 180 #elif defined(CONFIG_GEMINI)
207 /* should already be mapped by the kernel boot */ 181 /* should already be mapped by the kernel boot */
208 sccc = (volatile unsigned char __iomem *) 0xffeffb0d; 182 sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
209 sccd = (volatile unsigned char __iomem *) 0xffeffb08; 183 sccd = (volatile unsigned char __iomem *) 0xffeffb08;
210 TXRDY = 0x20; 184 TXRDY = 0x20;
211 RXRDY = 1; 185 RXRDY = 1;
212 DLAB = 0x80; 186 DLAB = 0x80;
213 #elif defined(CONFIG_405GP) 187 #elif defined(CONFIG_405GP)
214 sccc = (volatile unsigned char __iomem *)0xef600305; 188 sccc = (volatile unsigned char __iomem *)0xef600305;
215 sccd = (volatile unsigned char __iomem *)0xef600300; 189 sccd = (volatile unsigned char __iomem *)0xef600300;
216 TXRDY = 0x20; 190 TXRDY = 0x20;
217 RXRDY = 1; 191 RXRDY = 1;
218 DLAB = 0x80; 192 DLAB = 0x80;
219 #endif /* platform */ 193 #endif /* platform */
220
221 register_sysrq_key('x', &sysrq_xmon_op);
222 } 194 }
223 195
224 static int scc_initialized = 0; 196 static int scc_initialized = 0;
225 197
226 void xmon_init_scc(void); 198 void xmon_init_scc(void);
227 extern void cuda_poll(void); 199 extern void cuda_poll(void);
228 200
229 static inline void do_poll_adb(void) 201 static inline void do_poll_adb(void)
230 { 202 {
231 #ifdef CONFIG_ADB_PMU 203 #ifdef CONFIG_ADB_PMU
232 if (sys_ctrler == SYS_CTRLER_PMU) 204 if (sys_ctrler == SYS_CTRLER_PMU)
233 pmu_poll_adb(); 205 pmu_poll_adb();
234 #endif /* CONFIG_ADB_PMU */ 206 #endif /* CONFIG_ADB_PMU */
235 #ifdef CONFIG_ADB_CUDA 207 #ifdef CONFIG_ADB_CUDA
236 if (sys_ctrler == SYS_CTRLER_CUDA) 208 if (sys_ctrler == SYS_CTRLER_CUDA)
237 cuda_poll(); 209 cuda_poll();
238 #endif /* CONFIG_ADB_CUDA */ 210 #endif /* CONFIG_ADB_CUDA */
239 } 211 }
240 212
241 int 213 int xmon_write(void *ptr, int nb)
242 xmon_write(void *handle, void *ptr, int nb)
243 { 214 {
244 char *p = ptr; 215 char *p = ptr;
245 int i, c, ct; 216 int i, c, ct;
246 217
247 #ifdef CONFIG_SMP 218 #ifdef CONFIG_SMP
248 static unsigned long xmon_write_lock; 219 static unsigned long xmon_write_lock;
249 int lock_wait = 1000000; 220 int lock_wait = 1000000;
250 int locked; 221 int locked;
251 222
252 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) 223 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
253 if (--lock_wait == 0) 224 if (--lock_wait == 0)
254 break; 225 break;
255 #endif 226 #endif
256 227
257 #ifdef CONFIG_BOOTX_TEXT 228 #ifdef CONFIG_BOOTX_TEXT
258 if (use_screen) { 229 if (use_screen) {
259 /* write it on the screen */ 230 /* write it on the screen */
260 for (i = 0; i < nb; ++i) 231 for (i = 0; i < nb; ++i)
261 btext_drawchar(*p++); 232 btext_drawchar(*p++);
262 goto out; 233 goto out;
263 } 234 }
264 #endif 235 #endif
265 if (!scc_initialized) 236 if (!scc_initialized)
266 xmon_init_scc(); 237 xmon_init_scc();
267 ct = 0; 238 ct = 0;
268 for (i = 0; i < nb; ++i) { 239 for (i = 0; i < nb; ++i) {
269 while ((*sccc & TXRDY) == 0) 240 while ((*sccc & TXRDY) == 0)
270 do_poll_adb(); 241 do_poll_adb();
271 c = p[i]; 242 c = p[i];
272 if (c == '\n' && !ct) { 243 if (c == '\n' && !ct) {
273 c = '\r'; 244 c = '\r';
274 ct = 1; 245 ct = 1;
275 --i; 246 --i;
276 } else { 247 } else {
277 ct = 0; 248 ct = 0;
278 } 249 }
279 buf_access(); 250 buf_access();
280 *sccd = c; 251 *sccd = c;
281 eieio(); 252 eieio();
282 } 253 }
283 254
284 out: 255 out:
285 #ifdef CONFIG_SMP 256 #ifdef CONFIG_SMP
286 if (!locked) 257 if (!locked)
287 clear_bit(0, &xmon_write_lock); 258 clear_bit(0, &xmon_write_lock);
288 #endif 259 #endif
289 return nb; 260 return nb;
290 } 261 }
291 262
292 int xmon_wants_key; 263 int xmon_wants_key;
293 int xmon_adb_keycode; 264 int xmon_adb_keycode;
294 265
295 #ifdef CONFIG_BOOTX_TEXT 266 #ifdef CONFIG_BOOTX_TEXT
296 static int xmon_adb_shiftstate; 267 static int xmon_adb_shiftstate;
297 268
298 static unsigned char xmon_keytab[128] = 269 static unsigned char xmon_keytab[128] =
299 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ 270 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
300 "yt123465=97-80]o" /* 0x10 - 0x1f */ 271 "yt123465=97-80]o" /* 0x10 - 0x1f */
301 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ 272 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
302 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ 273 "\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 */ 274 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
304 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 275 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
305 276
306 static unsigned char xmon_shift_keytab[128] = 277 static unsigned char xmon_shift_keytab[128] =
307 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ 278 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
308 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ 279 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
309 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */ 280 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
310 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ 281 "\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 */ 282 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
312 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ 283 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
313 284
314 static int 285 static int xmon_get_adb_key(void)
315 xmon_get_adb_key(void)
316 { 286 {
317 int k, t, on; 287 int k, t, on;
318 288
319 xmon_wants_key = 1; 289 xmon_wants_key = 1;
320 for (;;) { 290 for (;;) {
321 xmon_adb_keycode = -1; 291 xmon_adb_keycode = -1;
322 t = 0; 292 t = 0;
323 on = 0; 293 on = 0;
324 do { 294 do {
325 if (--t < 0) { 295 if (--t < 0) {
326 on = 1 - on; 296 on = 1 - on;
327 btext_drawchar(on? 0xdb: 0x20); 297 btext_drawchar(on? 0xdb: 0x20);
328 btext_drawchar('\b'); 298 btext_drawchar('\b');
329 t = 200000; 299 t = 200000;
330 } 300 }
331 do_poll_adb(); 301 do_poll_adb();
332 } while (xmon_adb_keycode == -1); 302 } while (xmon_adb_keycode == -1);
333 k = xmon_adb_keycode; 303 k = xmon_adb_keycode;
334 if (on) 304 if (on)
335 btext_drawstring(" \b"); 305 btext_drawstring(" \b");
336 306
337 /* test for shift keys */ 307 /* test for shift keys */
338 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { 308 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
339 xmon_adb_shiftstate = (k & 0x80) == 0; 309 xmon_adb_shiftstate = (k & 0x80) == 0;
340 continue; 310 continue;
341 } 311 }
342 if (k >= 0x80) 312 if (k >= 0x80)
343 continue; /* ignore up transitions */ 313 continue; /* ignore up transitions */
344 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; 314 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
345 if (k != 0) 315 if (k != 0)
346 break; 316 break;
347 } 317 }
348 xmon_wants_key = 0; 318 xmon_wants_key = 0;
349 return k; 319 return k;
350 } 320 }
351 #endif /* CONFIG_BOOTX_TEXT */ 321 #endif /* CONFIG_BOOTX_TEXT */
352 322
353 int 323 int xmon_readchar(void)
354 xmon_read(void *handle, void *ptr, int nb)
355 { 324 {
356 char *p = ptr;
357 int i;
358
359 #ifdef CONFIG_BOOTX_TEXT 325 #ifdef CONFIG_BOOTX_TEXT
360 if (use_screen) { 326 if (use_screen)
361 for (i = 0; i < nb; ++i) 327 return xmon_get_adb_key();
362 *p++ = xmon_get_adb_key();
363 return i;
364 }
365 #endif 328 #endif
366 if (!scc_initialized) 329 if (!scc_initialized)
367 xmon_init_scc(); 330 xmon_init_scc();
368 for (i = 0; i < nb; ++i) {
369 while ((*sccc & RXRDY) == 0) 331 while ((*sccc & RXRDY) == 0)
370 do_poll_adb(); 332 do_poll_adb();
371 buf_access(); 333 buf_access();
372 *p++ = *sccd; 334 return *sccd;
373 }
374 return i;
375 } 335 }
376 336
377 int 337 int xmon_read_poll(void)
378 xmon_read_poll(void)
379 { 338 {
380 if ((*sccc & RXRDY) == 0) { 339 if ((*sccc & RXRDY) == 0) {
381 do_poll_adb(); 340 do_poll_adb();
382 return -1; 341 return -1;
383 } 342 }
384 buf_access(); 343 buf_access();
385 return *sccd; 344 return *sccd;
386 } 345 }
387 346
388 static unsigned char scc_inittab[] = { 347 static unsigned char scc_inittab[] = {
389 13, 0, /* set baud rate divisor */ 348 13, 0, /* set baud rate divisor */
390 12, 1, 349 12, 1,
391 14, 1, /* baud rate gen enable, src=rtxc */ 350 14, 1, /* baud rate gen enable, src=rtxc */
392 11, 0x50, /* clocks = br gen */ 351 11, 0x50, /* clocks = br gen */
393 5, 0xea, /* tx 8 bits, assert DTR & RTS */ 352 5, 0xea, /* tx 8 bits, assert DTR & RTS */
394 4, 0x46, /* x16 clock, 1 stop */ 353 4, 0x46, /* x16 clock, 1 stop */
395 3, 0xc1, /* rx enable, 8 bits */ 354 3, 0xc1, /* rx enable, 8 bits */
396 }; 355 };
397 356
398 void 357 void xmon_init_scc(void)
399 xmon_init_scc(void)
400 { 358 {
401 if ( _machine == _MACH_chrp ) 359 if ( _machine == _MACH_chrp )
402 { 360 {
403 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ 361 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
404 sccd[0] = 12; eieio(); /* DLL = 9600 baud */ 362 sccd[0] = 12; eieio(); /* DLL = 9600 baud */
405 sccd[1] = 0; eieio(); 363 sccd[1] = 0; eieio();
406 sccd[2] = 0; eieio(); /* FCR = 0 */ 364 sccd[2] = 0; eieio(); /* FCR = 0 */
407 sccd[3] = 3; eieio(); /* LCR = 8N1 */ 365 sccd[3] = 3; eieio(); /* LCR = 8N1 */
408 sccd[1] = 0; eieio(); /* IER = 0 */ 366 sccd[1] = 0; eieio(); /* IER = 0 */
409 } 367 }
410 else if ( _machine == _MACH_Pmac ) 368 else if ( _machine == _MACH_Pmac )
411 { 369 {
412 int i, x; 370 int i, x;
371 unsigned long timeout;
413 372
414 if (channel_node != 0) 373 if (channel_node != 0)
415 pmac_call_feature( 374 pmac_call_feature(
416 PMAC_FTR_SCC_ENABLE, 375 PMAC_FTR_SCC_ENABLE,
417 channel_node, 376 channel_node,
418 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); 377 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
419 printk(KERN_INFO "Serial port locked ON by debugger !\n"); 378 printk(KERN_INFO "Serial port locked ON by debugger !\n");
420 if (via_modem && channel_node != 0) { 379 if (via_modem && channel_node != 0) {
421 unsigned int t0; 380 unsigned int t0;
422 381
423 pmac_call_feature( 382 pmac_call_feature(
424 PMAC_FTR_MODEM_ENABLE, 383 PMAC_FTR_MODEM_ENABLE,
425 channel_node, 0, 1); 384 channel_node, 0, 1);
426 printk(KERN_INFO "Modem powered up by debugger !\n"); 385 printk(KERN_INFO "Modem powered up by debugger !\n");
427 t0 = readtb(); 386 t0 = get_tbl();
428 while (readtb() - t0 < 3*TB_SPEED) 387 timeout = 3 * tb_ticks_per_sec;
388 if (timeout == 0)
389 /* assume 25MHz if tb_ticks_per_sec not set */
390 timeout = 75000000;
391 while (get_tbl() - t0 < timeout)
429 eieio(); 392 eieio();
430 } 393 }
431 /* use the B channel if requested */ 394 /* use the B channel if requested */
432 if (xmon_use_sccb) { 395 if (xmon_use_sccb) {
433 sccc = (volatile unsigned char *) 396 sccc = (volatile unsigned char *)
434 ((unsigned long)sccc & ~0x20); 397 ((unsigned long)sccc & ~0x20);
435 sccd = sccc + 0x10; 398 sccd = sccc + 0x10;
436 } 399 }
437 for (i = 20000; i != 0; --i) { 400 for (i = 20000; i != 0; --i) {
438 x = *sccc; eieio(); 401 x = *sccc; eieio();
439 } 402 }
440 *sccc = 9; eieio(); /* reset A or B side */ 403 *sccc = 9; eieio(); /* reset A or B side */
441 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); 404 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
442 for (i = 0; i < sizeof(scc_inittab); ++i) { 405 for (i = 0; i < sizeof(scc_inittab); ++i) {
443 *sccc = scc_inittab[i]; 406 *sccc = scc_inittab[i];
444 eieio(); 407 eieio();
445 } 408 }
446 } 409 }
447 scc_initialized = 1; 410 scc_initialized = 1;
448 if (via_modem) { 411 if (via_modem) {
449 for (;;) { 412 for (;;) {
450 xmon_write(NULL, "ATE1V1\r", 7); 413 xmon_write("ATE1V1\r", 7);
451 if (xmon_expect("OK", 5)) { 414 if (xmon_expect("OK", 5)) {
452 xmon_write(NULL, "ATA\r", 4); 415 xmon_write("ATA\r", 4);
453 if (xmon_expect("CONNECT", 40)) 416 if (xmon_expect("CONNECT", 40))
454 break; 417 break;
455 } 418 }
456 xmon_write(NULL, "+++", 3); 419 xmon_write("+++", 3);
457 xmon_expect("OK", 3); 420 xmon_expect("OK", 3);
458 } 421 }
459 } 422 }
460 } 423 }
461 424
462 void *xmon_stdin; 425 void xmon_enter(void)
463 void *xmon_stdout;
464 void *xmon_stderr;
465
466 int xmon_putc(int c, void *f)
467 { 426 {
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 427 #ifdef CONFIG_ADB_PMU
610 if (_machine == _MACH_Pmac) { 428 if (_machine == _MACH_Pmac) {
611 pmu_suspend(); 429 pmu_suspend();
612 } 430 }
613 #endif 431 #endif
614 } 432 }
615 433
616 void 434 void xmon_leave(void)
617 xmon_leave(void)
618 { 435 {
arch/powerpc/xmon/start_64.c
1 /* 1 /*
2 * Copyright (C) 1996 Paul Mackerras. 2 * Copyright (C) 1996 Paul Mackerras.
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version. 7 * 2 of the License, or (at your option) any later version.
8 */ 8 */
9 #include <linux/config.h>
10 #include <linux/string.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/sysrq.h>
14 #include <linux/init.h>
15 #include <asm/machdep.h> 9 #include <asm/machdep.h>
16 #include <asm/io.h>
17 #include <asm/page.h>
18 #include <asm/prom.h>
19 #include <asm/processor.h>
20 #include <asm/udbg.h> 10 #include <asm/udbg.h>
21 #include <asm/system.h>
22 #include "nonstdio.h" 11 #include "nonstdio.h"
23 12
24 #ifdef CONFIG_MAGIC_SYSRQ 13 void xmon_map_scc(void)
25
26 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
27 struct tty_struct *tty)
28 { 14 {
29 /* ensure xmon is enabled */
30 xmon_init(1);
31 debugger(pt_regs);
32 } 15 }
33 16
34 static struct sysrq_key_op sysrq_xmon_op = 17 int xmon_write(void *ptr, int nb)
35 { 18 {
36 .handler = sysrq_handle_xmon,
37 .help_msg = "Xmon",
38 .action_msg = "Entering xmon",
39 };
40
41 static int __init setup_xmon_sysrq(void)
42 {
43 register_sysrq_key('x', &sysrq_xmon_op);
44 return 0;
45 }
46 __initcall(setup_xmon_sysrq);
47 #endif /* CONFIG_MAGIC_SYSRQ */
48
49 int
50 xmon_write(void *handle, void *ptr, int nb)
51 {
52 return udbg_write(ptr, nb); 19 return udbg_write(ptr, nb);
53 } 20 }
54 21
55 int 22 int xmon_readchar(void)
56 xmon_read(void *handle, void *ptr, int nb)
57 { 23 {
58 return udbg_read(ptr, nb); 24 if (udbg_getc)
25 return udbg_getc();
26 return -1;
59 } 27 }
60 28
61 int 29 int xmon_read_poll(void)
62 xmon_read_poll(void)
63 { 30 {
64 if (udbg_getc_poll) 31 if (udbg_getc_poll)
65 return udbg_getc_poll(); 32 return udbg_getc_poll();
66 return -1; 33 return -1;
67 }
68
69 FILE *xmon_stdin;
70 FILE *xmon_stdout;
71
72 int
73 xmon_putc(int c, void *f)
74 {
75 char ch = c;
76
77 if (c == '\n')
78 xmon_putc('\r', f);
79 return xmon_write(f, &ch, 1) == 1? c: -1;
80 }
81
82 int
83 xmon_putchar(int c)
84 {
85 return xmon_putc(c, xmon_stdout);
86 }
87
88 int
89 xmon_fputs(char *str, void *f)
90 {
91 int n = strlen(str);
92
93 return xmon_write(f, str, n) == n? 0: -1;
94 }
95
96 int
97 xmon_readchar(void)
98 {
99 char ch;
100
101 for (;;) {
102 switch (xmon_read(xmon_stdin, &ch, 1)) {
103 case 1:
104 return ch;
105 case -1:
106 xmon_printf("read(stdin) returned -1\r\n", 0, 0);
107 return -1;
108 }
109 }
110 }
111
112 static char line[256];
113 static char *lineptr;
114 static int lineleft;
115
116 int
117 xmon_getchar(void)
118 {
119 int c;
120
121 if (lineleft == 0) {
122 lineptr = line;
123 for (;;) {
124 c = xmon_readchar();
125 if (c == -1 || c == 4)
126 break;
127 if (c == '\r' || c == '\n') {
128 *lineptr++ = '\n';
129 xmon_putchar('\n');
130 break;
131 }
132 switch (c) {
133 case 0177:
134 case '\b':
135 if (lineptr > line) {
136 xmon_putchar('\b');
137 xmon_putchar(' ');
138 xmon_putchar('\b');
139 --lineptr;
140 }
141 break;
142 case 'U' & 0x1F:
143 while (lineptr > line) {
144 xmon_putchar('\b');
145 xmon_putchar(' ');
146 xmon_putchar('\b');
147 --lineptr;
148 }
149 break;
150 default:
151 if (lineptr >= &line[sizeof(line) - 1])
152 xmon_putchar('\a');
153 else {
154 xmon_putchar(c);
155 *lineptr++ = c;
156 }
157 }
158 }
159 lineleft = lineptr - line;
160 lineptr = line;
161 }
162 if (lineleft == 0)
163 return -1;
164 --lineleft;
165 return *lineptr++;
166 }
167
168 char *
169 xmon_fgets(char *str, int nb, void *f)
170 {
171 char *p;
172 int c;
173
174 for (p = str; p < str + nb - 1; ) {
175 c = xmon_getchar();
176 if (c == -1) {
177 if (p == str)
178 return NULL;
179 break;
180 }
181 *p++ = c;
182 if (c == '\n')
183 break;
184 }
185 *p = 0;
186 return str;
arch/powerpc/xmon/start_8xx.c
1 /* 1 /*
2 * Copyright (C) 1996 Paul Mackerras. 2 * Copyright (C) 1996 Paul Mackerras.
3 * Copyright (C) 2000 Dan Malek. 3 * Copyright (C) 2000 Dan Malek.
4 * Quick hack of Paul's code to make XMON work on 8xx processors. Lots 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 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. 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 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. 8 * changes between boot up and operational phases of the kernel.
9 */ 9 */
10 #include <linux/string.h> 10 #include <linux/string.h>
11 #include <asm/machdep.h> 11 #include <asm/machdep.h>
12 #include <asm/io.h> 12 #include <asm/io.h>
13 #include <asm/page.h> 13 #include <asm/page.h>
14 #include <linux/kernel.h> 14 #include <linux/kernel.h>
15 #include <asm/8xx_immap.h> 15 #include <asm/8xx_immap.h>
16 #include <asm/mpc8xx.h> 16 #include <asm/mpc8xx.h>
17 #include <asm/commproc.h> 17 #include <asm/commproc.h>
18 #include "nonstdio.h"
18 19
19 extern void xmon_printf(const char *fmt, ...);
20 extern int xmon_8xx_write(char *str, int nb); 20 extern int xmon_8xx_write(char *str, int nb);
21 extern int xmon_8xx_read_poll(void); 21 extern int xmon_8xx_read_poll(void);
22 extern int xmon_8xx_read_char(void); 22 extern int xmon_8xx_read_char(void);
23 void prom_drawhex(uint);
24 void prom_drawstring(const char *str);
25 23
26 static int use_screen = 1; /* default */ 24 void xmon_map_scc(void)
27
28 #define TB_SPEED 25000000
29
30 static inline unsigned int readtb(void)
31 { 25 {
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); 26 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
47 use_screen = 0;
48
49 prom_drawstring("xmon uses serial port\n");
50 } 27 }
51 28
52 static int scc_initialized = 0;
53
54 void xmon_init_scc(void); 29 void xmon_init_scc(void);
55 30
56 int 31 int xmon_write(void *ptr, int nb)
57 xmon_write(void *handle, void *ptr, int nb)
58 { 32 {
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)); 33 return(xmon_8xx_write(ptr, nb));
66 } 34 }
67 35
68 int xmon_wants_key; 36 int xmon_readchar(void)
69
70 int
71 xmon_read(void *handle, void *ptr, int nb)
72 { 37 {
73 char *p = ptr; 38 return xmon_8xx_read_char();
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 } 39 }
84 40
85 int 41 int xmon_read_poll(void)
86 xmon_read_poll(void)
87 { 42 {
88 return(xmon_8xx_read_poll()); 43 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 } 44 }
arch/powerpc/xmon/subr_prf.c
1 /* File was deleted
2 * Written by Cort Dougan to replace the version originally used
3 * by Paul Mackerras, which came from NetBSD and thus had copyright
4 * conflicts with Linux.
5 *
6 * This file makes liberal use of the standard linux utility
7 * routines to reduce the size of the binary. We assume we can
8 * trust some parts of Linux inside the debugger.
9 * -- Cort (cort@cs.nmt.edu)
10 *
11 * Copyright (C) 1999 Cort Dougan.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
17 */
18
19 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/module.h>
22 #include <stdarg.h>
23 #include "nonstdio.h"
24
25 extern int xmon_write(void *, void *, int);
26
27 void xmon_vfprintf(void *f, const char *fmt, va_list ap)
28 {
29 static char xmon_buf[2048];
30 int n;
31
32 n = vsprintf(xmon_buf, fmt, ap);
33 xmon_write(f, xmon_buf, n);
34 }
35
36 void xmon_printf(const char *fmt, ...)
37 {
38 va_list ap;
39
40 va_start(ap, fmt);
41 xmon_vfprintf(stdout, fmt, ap);
42 va_end(ap);
43 }
44 EXPORT_SYMBOL(xmon_printf);
45
46 void xmon_fprintf(void *f, const char *fmt, ...)
47 {
48 va_list ap;
49
50 va_start(ap, fmt);
51 xmon_vfprintf(f, fmt, ap);
52 va_end(ap);
53 }
54 1 /*
55 2 * Written by Cort Dougan to replace the version originally used
arch/powerpc/xmon/xmon.c
1 /* 1 /*
2 * Routines providing a simple monitor for use on the PowerMac. 2 * Routines providing a simple monitor for use on the PowerMac.
3 * 3 *
4 * Copyright (C) 1996 Paul Mackerras. 4 * Copyright (C) 1996-2005 Paul Mackerras.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 #include <linux/config.h> 11 #include <linux/config.h>
12 #include <linux/errno.h> 12 #include <linux/errno.h>
13 #include <linux/sched.h> 13 #include <linux/sched.h>
14 #include <linux/smp.h> 14 #include <linux/smp.h>
15 #include <linux/mm.h> 15 #include <linux/mm.h>
16 #include <linux/reboot.h> 16 #include <linux/reboot.h>
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 #include <linux/module.h>
21 #include <linux/sysrq.h>
21 22
22 #include <asm/ptrace.h> 23 #include <asm/ptrace.h>
23 #include <asm/string.h> 24 #include <asm/string.h>
24 #include <asm/prom.h> 25 #include <asm/prom.h>
25 #include <asm/machdep.h> 26 #include <asm/machdep.h>
26 #include <asm/xmon.h> 27 #include <asm/xmon.h>
27 #ifdef CONFIG_PMAC_BACKLIGHT 28 #ifdef CONFIG_PMAC_BACKLIGHT
28 #include <asm/backlight.h> 29 #include <asm/backlight.h>
29 #endif 30 #endif
30 #include <asm/processor.h> 31 #include <asm/processor.h>
31 #include <asm/pgtable.h> 32 #include <asm/pgtable.h>
32 #include <asm/mmu.h> 33 #include <asm/mmu.h>
33 #include <asm/mmu_context.h> 34 #include <asm/mmu_context.h>
34 #include <asm/cputable.h> 35 #include <asm/cputable.h>
35 #include <asm/rtas.h> 36 #include <asm/rtas.h>
36 #include <asm/sstep.h> 37 #include <asm/sstep.h>
37 #include <asm/bug.h> 38 #include <asm/bug.h>
38 39
39 #ifdef CONFIG_PPC64 40 #ifdef CONFIG_PPC64
40 #include <asm/hvcall.h> 41 #include <asm/hvcall.h>
41 #include <asm/paca.h> 42 #include <asm/paca.h>
42 #endif 43 #endif
43 44
44 #include "nonstdio.h" 45 #include "nonstdio.h"
45 46
46 #define scanhex xmon_scanhex 47 #define scanhex xmon_scanhex
47 #define skipbl xmon_skipbl 48 #define skipbl xmon_skipbl
48 49
49 #ifdef CONFIG_SMP 50 #ifdef CONFIG_SMP
50 cpumask_t cpus_in_xmon = CPU_MASK_NONE; 51 cpumask_t cpus_in_xmon = CPU_MASK_NONE;
51 static unsigned long xmon_taken = 1; 52 static unsigned long xmon_taken = 1;
52 static int xmon_owner; 53 static int xmon_owner;
53 static int xmon_gate; 54 static int xmon_gate;
54 #endif /* CONFIG_SMP */ 55 #endif /* CONFIG_SMP */
55 56
56 static unsigned long in_xmon = 0; 57 static unsigned long in_xmon = 0;
57 58
58 static unsigned long adrs; 59 static unsigned long adrs;
59 static int size = 1; 60 static int size = 1;
60 #define MAX_DUMP (128 * 1024) 61 #define MAX_DUMP (128 * 1024)
61 static unsigned long ndump = 64; 62 static unsigned long ndump = 64;
62 static unsigned long nidump = 16; 63 static unsigned long nidump = 16;
63 static unsigned long ncsum = 4096; 64 static unsigned long ncsum = 4096;
64 static int termch; 65 static int termch;
65 static char tmpstr[128]; 66 static char tmpstr[128];
66 67
67 #define JMP_BUF_LEN 23 68 #define JMP_BUF_LEN 23
68 static long bus_error_jmp[JMP_BUF_LEN]; 69 static long bus_error_jmp[JMP_BUF_LEN];
69 static int catch_memory_errors; 70 static int catch_memory_errors;
70 static long *xmon_fault_jmp[NR_CPUS]; 71 static long *xmon_fault_jmp[NR_CPUS];
71 #define setjmp xmon_setjmp 72 #define setjmp xmon_setjmp
72 #define longjmp xmon_longjmp 73 #define longjmp xmon_longjmp
73 74
74 /* Breakpoint stuff */ 75 /* Breakpoint stuff */
75 struct bpt { 76 struct bpt {
76 unsigned long address; 77 unsigned long address;
77 unsigned int instr[2]; 78 unsigned int instr[2];
78 atomic_t ref_count; 79 atomic_t ref_count;
79 int enabled; 80 int enabled;
80 unsigned long pad; 81 unsigned long pad;
81 }; 82 };
82 83
83 /* Bits in bpt.enabled */ 84 /* Bits in bpt.enabled */
84 #define BP_IABR_TE 1 /* IABR translation enabled */ 85 #define BP_IABR_TE 1 /* IABR translation enabled */
85 #define BP_IABR 2 86 #define BP_IABR 2
86 #define BP_TRAP 8 87 #define BP_TRAP 8
87 #define BP_DABR 0x10 88 #define BP_DABR 0x10
88 89
89 #define NBPTS 256 90 #define NBPTS 256
90 static struct bpt bpts[NBPTS]; 91 static struct bpt bpts[NBPTS];
91 static struct bpt dabr; 92 static struct bpt dabr;
92 static struct bpt *iabr; 93 static struct bpt *iabr;
93 static unsigned bpinstr = 0x7fe00008; /* trap */ 94 static unsigned bpinstr = 0x7fe00008; /* trap */
94 95
95 #define BP_NUM(bp) ((bp) - bpts + 1) 96 #define BP_NUM(bp) ((bp) - bpts + 1)
96 97
97 /* Prototypes */ 98 /* Prototypes */
98 static int cmds(struct pt_regs *); 99 static int cmds(struct pt_regs *);
99 static int mread(unsigned long, void *, int); 100 static int mread(unsigned long, void *, int);
100 static int mwrite(unsigned long, void *, int); 101 static int mwrite(unsigned long, void *, int);
101 static int handle_fault(struct pt_regs *); 102 static int handle_fault(struct pt_regs *);
102 static void byterev(unsigned char *, int); 103 static void byterev(unsigned char *, int);
103 static void memex(void); 104 static void memex(void);
104 static int bsesc(void); 105 static int bsesc(void);
105 static void dump(void); 106 static void dump(void);
106 static void prdump(unsigned long, long); 107 static void prdump(unsigned long, long);
107 static int ppc_inst_dump(unsigned long, long, int); 108 static int ppc_inst_dump(unsigned long, long, int);
108 void print_address(unsigned long); 109 void print_address(unsigned long);
109 static void backtrace(struct pt_regs *); 110 static void backtrace(struct pt_regs *);
110 static void excprint(struct pt_regs *); 111 static void excprint(struct pt_regs *);
111 static void prregs(struct pt_regs *); 112 static void prregs(struct pt_regs *);
112 static void memops(int); 113 static void memops(int);
113 static void memlocate(void); 114 static void memlocate(void);
114 static void memzcan(void); 115 static void memzcan(void);
115 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned); 116 static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
116 int skipbl(void); 117 int skipbl(void);
117 int scanhex(unsigned long *valp); 118 int scanhex(unsigned long *valp);
118 static void scannl(void); 119 static void scannl(void);
119 static int hexdigit(int); 120 static int hexdigit(int);
120 void getstring(char *, int); 121 void getstring(char *, int);
121 static void flush_input(void); 122 static void flush_input(void);
122 static int inchar(void); 123 static int inchar(void);
123 static void take_input(char *); 124 static void take_input(char *);
124 static unsigned long read_spr(int); 125 static unsigned long read_spr(int);
125 static void write_spr(int, unsigned long); 126 static void write_spr(int, unsigned long);
126 static void super_regs(void); 127 static void super_regs(void);
127 static void remove_bpts(void); 128 static void remove_bpts(void);
128 static void insert_bpts(void); 129 static void insert_bpts(void);
129 static void remove_cpu_bpts(void); 130 static void remove_cpu_bpts(void);
130 static void insert_cpu_bpts(void); 131 static void insert_cpu_bpts(void);
131 static struct bpt *at_breakpoint(unsigned long pc); 132 static struct bpt *at_breakpoint(unsigned long pc);
132 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp); 133 static struct bpt *in_breakpoint_table(unsigned long pc, unsigned long *offp);
133 static int do_step(struct pt_regs *); 134 static int do_step(struct pt_regs *);
134 static void bpt_cmds(void); 135 static void bpt_cmds(void);
135 static void cacheflush(void); 136 static void cacheflush(void);
136 static int cpu_cmd(void); 137 static int cpu_cmd(void);
137 static void csum(void); 138 static void csum(void);
138 static void bootcmds(void); 139 static void bootcmds(void);
139 static void proccall(void); 140 static void proccall(void);
140 void dump_segments(void); 141 void dump_segments(void);
141 static void symbol_lookup(void); 142 static void symbol_lookup(void);
142 static void xmon_print_symbol(unsigned long address, const char *mid, 143 static void xmon_print_symbol(unsigned long address, const char *mid,
143 const char *after); 144 const char *after);
144 static const char *getvecname(unsigned long vec); 145 static const char *getvecname(unsigned long vec);
145 146
146 extern int print_insn_powerpc(unsigned long, unsigned long, int); 147 extern int print_insn_powerpc(unsigned long, unsigned long, int);
147 extern void printf(const char *fmt, ...);
148 extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
149 extern int xmon_putc(int c, void *f);
150 extern int putchar(int ch);
151 148
152 extern void xmon_enter(void); 149 extern void xmon_enter(void);
153 extern void xmon_leave(void); 150 extern void xmon_leave(void);
154 151
155 extern int xmon_read_poll(void);
156 extern long setjmp(long *); 152 extern long setjmp(long *);
157 extern void longjmp(long *, long); 153 extern void longjmp(long *, long);
158 extern void xmon_save_regs(struct pt_regs *); 154 extern void xmon_save_regs(struct pt_regs *);
159 155
160 #ifdef CONFIG_PPC64 156 #ifdef CONFIG_PPC64
161 #define REG "%.16lx" 157 #define REG "%.16lx"
162 #define REGS_PER_LINE 4 158 #define REGS_PER_LINE 4
163 #define LAST_VOLATILE 13 159 #define LAST_VOLATILE 13
164 #else 160 #else
165 #define REG "%.8lx" 161 #define REG "%.8lx"
166 #define REGS_PER_LINE 8 162 #define REGS_PER_LINE 8
167 #define LAST_VOLATILE 12 163 #define LAST_VOLATILE 12
168 #endif 164 #endif
169 165
170 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3]) 166 #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
171 167
172 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 168 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
173 || ('a' <= (c) && (c) <= 'f') \ 169 || ('a' <= (c) && (c) <= 'f') \
174 || ('A' <= (c) && (c) <= 'F')) 170 || ('A' <= (c) && (c) <= 'F'))
175 #define isalnum(c) (('0' <= (c) && (c) <= '9') \ 171 #define isalnum(c) (('0' <= (c) && (c) <= '9') \
176 || ('a' <= (c) && (c) <= 'z') \ 172 || ('a' <= (c) && (c) <= 'z') \
177 || ('A' <= (c) && (c) <= 'Z')) 173 || ('A' <= (c) && (c) <= 'Z'))
178 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0) 174 #define isspace(c) (c == ' ' || c == '\t' || c == 10 || c == 13 || c == 0)
179 175
180 static char *help_string = "\ 176 static char *help_string = "\
181 Commands:\n\ 177 Commands:\n\
182 b show breakpoints\n\ 178 b show breakpoints\n\
183 bd set data breakpoint\n\ 179 bd set data breakpoint\n\
184 bi set instruction breakpoint\n\ 180 bi set instruction breakpoint\n\
185 bc clear breakpoint\n" 181 bc clear breakpoint\n"
186 #ifdef CONFIG_SMP 182 #ifdef CONFIG_SMP
187 "\ 183 "\
188 c print cpus stopped in xmon\n\ 184 c print cpus stopped in xmon\n\
189 c# try to switch to cpu number h (in hex)\n" 185 c# try to switch to cpu number h (in hex)\n"
190 #endif 186 #endif
191 "\ 187 "\
192 C checksum\n\ 188 C checksum\n\
193 d dump bytes\n\ 189 d dump bytes\n\
194 di dump instructions\n\ 190 di dump instructions\n\
195 df dump float values\n\ 191 df dump float values\n\
196 dd dump double values\n\ 192 dd dump double values\n\
197 e print exception information\n\ 193 e print exception information\n\
198 f flush cache\n\ 194 f flush cache\n\
199 la lookup symbol+offset of specified address\n\ 195 la lookup symbol+offset of specified address\n\
200 ls lookup address of specified symbol\n\ 196 ls lookup address of specified symbol\n\
201 m examine/change memory\n\ 197 m examine/change memory\n\
202 mm move a block of memory\n\ 198 mm move a block of memory\n\
203 ms set a block of memory\n\ 199 ms set a block of memory\n\
204 md compare two blocks of memory\n\ 200 md compare two blocks of memory\n\
205 ml locate a block of memory\n\ 201 ml locate a block of memory\n\
206 mz zero a block of memory\n\ 202 mz zero a block of memory\n\
207 mi show information about memory allocation\n\ 203 mi show information about memory allocation\n\
208 p call a procedure\n\ 204 p call a procedure\n\
209 r print registers\n\ 205 r print registers\n\
210 s single step\n\ 206 s single step\n\
211 S print special registers\n\ 207 S print special registers\n\
212 t print backtrace\n\ 208 t print backtrace\n\
213 x exit monitor and recover\n\ 209 x exit monitor and recover\n\
214 X exit monitor and dont recover\n" 210 X exit monitor and dont recover\n"
215 #ifdef CONFIG_PPC64 211 #ifdef CONFIG_PPC64
216 " u dump segment table or SLB\n" 212 " u dump segment table or SLB\n"
217 #endif 213 #endif
218 #ifdef CONFIG_PPC_STD_MMU_32 214 #ifdef CONFIG_PPC_STD_MMU_32
219 " u dump segment registers\n" 215 " u dump segment registers\n"
220 #endif 216 #endif
221 " ? help\n" 217 " ? help\n"
222 " zr reboot\n\ 218 " zr reboot\n\
223 zh halt\n" 219 zh halt\n"
224 ; 220 ;
225 221
226 static struct pt_regs *xmon_regs; 222 static struct pt_regs *xmon_regs;
227 223
228 static inline void sync(void) 224 static inline void sync(void)
229 { 225 {
230 asm volatile("sync; isync"); 226 asm volatile("sync; isync");
231 } 227 }
232 228
233 static inline void store_inst(void *p) 229 static inline void store_inst(void *p)
234 { 230 {
235 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); 231 asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
236 } 232 }
237 233
238 static inline void cflush(void *p) 234 static inline void cflush(void *p)
239 { 235 {
240 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); 236 asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
241 } 237 }
242 238
243 static inline void cinval(void *p) 239 static inline void cinval(void *p)
244 { 240 {
245 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p)); 241 asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
246 } 242 }
247 243
248 /* 244 /*
249 * Disable surveillance (the service processor watchdog function) 245 * Disable surveillance (the service processor watchdog function)
250 * while we are in xmon. 246 * while we are in xmon.
251 * XXX we should re-enable it when we leave. :) 247 * XXX we should re-enable it when we leave. :)
252 */ 248 */
253 #define SURVEILLANCE_TOKEN 9000 249 #define SURVEILLANCE_TOKEN 9000
254 250
255 static inline void disable_surveillance(void) 251 static inline void disable_surveillance(void)
256 { 252 {
257 #ifdef CONFIG_PPC_PSERIES 253 #ifdef CONFIG_PPC_PSERIES
258 /* Since this can't be a module, args should end up below 4GB. */ 254 /* Since this can't be a module, args should end up below 4GB. */
259 static struct rtas_args args; 255 static struct rtas_args args;
260 256
261 /* 257 /*
262 * At this point we have got all the cpus we can into 258 * At this point we have got all the cpus we can into
263 * xmon, so there is hopefully no other cpu calling RTAS 259 * xmon, so there is hopefully no other cpu calling RTAS
264 * at the moment, even though we don't take rtas.lock. 260 * at the moment, even though we don't take rtas.lock.
265 * If we did try to take rtas.lock there would be a 261 * If we did try to take rtas.lock there would be a
266 * real possibility of deadlock. 262 * real possibility of deadlock.
267 */ 263 */
268 args.token = rtas_token("set-indicator"); 264 args.token = rtas_token("set-indicator");
269 if (args.token == RTAS_UNKNOWN_SERVICE) 265 if (args.token == RTAS_UNKNOWN_SERVICE)
270 return; 266 return;
271 args.nargs = 3; 267 args.nargs = 3;
272 args.nret = 1; 268 args.nret = 1;
273 args.rets = &args.args[3]; 269 args.rets = &args.args[3];
274 args.args[0] = SURVEILLANCE_TOKEN; 270 args.args[0] = SURVEILLANCE_TOKEN;
275 args.args[1] = 0; 271 args.args[1] = 0;
276 args.args[2] = 0; 272 args.args[2] = 0;
277 enter_rtas(__pa(&args)); 273 enter_rtas(__pa(&args));
278 #endif /* CONFIG_PPC_PSERIES */ 274 #endif /* CONFIG_PPC_PSERIES */
279 } 275 }
280 276
281 #ifdef CONFIG_SMP 277 #ifdef CONFIG_SMP
282 static int xmon_speaker; 278 static int xmon_speaker;
283 279
284 static void get_output_lock(void) 280 static void get_output_lock(void)
285 { 281 {
286 int me = smp_processor_id() + 0x100; 282 int me = smp_processor_id() + 0x100;
287 int last_speaker = 0, prev; 283 int last_speaker = 0, prev;
288 long timeout; 284 long timeout;
289 285
290 if (xmon_speaker == me) 286 if (xmon_speaker == me)
291 return; 287 return;
292 for (;;) { 288 for (;;) {
293 if (xmon_speaker == 0) { 289 if (xmon_speaker == 0) {
294 last_speaker = cmpxchg(&xmon_speaker, 0, me); 290 last_speaker = cmpxchg(&xmon_speaker, 0, me);
295 if (last_speaker == 0) 291 if (last_speaker == 0)
296 return; 292 return;
297 } 293 }
298 timeout = 10000000; 294 timeout = 10000000;
299 while (xmon_speaker == last_speaker) { 295 while (xmon_speaker == last_speaker) {
300 if (--timeout > 0) 296 if (--timeout > 0)
301 continue; 297 continue;
302 /* hostile takeover */ 298 /* hostile takeover */
303 prev = cmpxchg(&xmon_speaker, last_speaker, me); 299 prev = cmpxchg(&xmon_speaker, last_speaker, me);
304 if (prev == last_speaker) 300 if (prev == last_speaker)
305 return; 301 return;
306 break; 302 break;
307 } 303 }
308 } 304 }
309 } 305 }
310 306
311 static void release_output_lock(void) 307 static void release_output_lock(void)
312 { 308 {
313 xmon_speaker = 0; 309 xmon_speaker = 0;
314 } 310 }
315 #endif 311 #endif
316 312
317 int xmon_core(struct pt_regs *regs, int fromipi) 313 int xmon_core(struct pt_regs *regs, int fromipi)
318 { 314 {
319 int cmd = 0; 315 int cmd = 0;
320 unsigned long msr; 316 unsigned long msr;
321 struct bpt *bp; 317 struct bpt *bp;
322 long recurse_jmp[JMP_BUF_LEN]; 318 long recurse_jmp[JMP_BUF_LEN];
323 unsigned long offset; 319 unsigned long offset;
324 #ifdef CONFIG_SMP 320 #ifdef CONFIG_SMP
325 int cpu; 321 int cpu;
326 int secondary; 322 int secondary;
327 unsigned long timeout; 323 unsigned long timeout;
328 #endif 324 #endif
329 325
330 msr = mfmsr(); 326 msr = mfmsr();
331 mtmsr(msr & ~MSR_EE); /* disable interrupts */ 327 mtmsr(msr & ~MSR_EE); /* disable interrupts */
332 328
333 bp = in_breakpoint_table(regs->nip, &offset); 329 bp = in_breakpoint_table(regs->nip, &offset);
334 if (bp != NULL) { 330 if (bp != NULL) {
335 regs->nip = bp->address + offset; 331 regs->nip = bp->address + offset;
336 atomic_dec(&bp->ref_count); 332 atomic_dec(&bp->ref_count);
337 } 333 }
338 334
339 remove_cpu_bpts(); 335 remove_cpu_bpts();
340 336
341 #ifdef CONFIG_SMP 337 #ifdef CONFIG_SMP
342 cpu = smp_processor_id(); 338 cpu = smp_processor_id();
343 if (cpu_isset(cpu, cpus_in_xmon)) { 339 if (cpu_isset(cpu, cpus_in_xmon)) {
344 get_output_lock(); 340 get_output_lock();
345 excprint(regs); 341 excprint(regs);
346 printf("cpu 0x%x: Exception %lx %s in xmon, " 342 printf("cpu 0x%x: Exception %lx %s in xmon, "
347 "returning to main loop\n", 343 "returning to main loop\n",
348 cpu, regs->trap, getvecname(TRAP(regs))); 344 cpu, regs->trap, getvecname(TRAP(regs)));
349 release_output_lock(); 345 release_output_lock();
350 longjmp(xmon_fault_jmp[cpu], 1); 346 longjmp(xmon_fault_jmp[cpu], 1);
351 } 347 }
352 348
353 if (setjmp(recurse_jmp) != 0) { 349 if (setjmp(recurse_jmp) != 0) {
354 if (!in_xmon || !xmon_gate) { 350 if (!in_xmon || !xmon_gate) {
355 get_output_lock(); 351 get_output_lock();
356 printf("xmon: WARNING: bad recursive fault " 352 printf("xmon: WARNING: bad recursive fault "
357 "on cpu 0x%x\n", cpu); 353 "on cpu 0x%x\n", cpu);
358 release_output_lock(); 354 release_output_lock();
359 goto waiting; 355 goto waiting;
360 } 356 }
361 secondary = !(xmon_taken && cpu == xmon_owner); 357 secondary = !(xmon_taken && cpu == xmon_owner);
362 goto cmdloop; 358 goto cmdloop;
363 } 359 }
364 360
365 xmon_fault_jmp[cpu] = recurse_jmp; 361 xmon_fault_jmp[cpu] = recurse_jmp;
366 cpu_set(cpu, cpus_in_xmon); 362 cpu_set(cpu, cpus_in_xmon);
367 363
368 bp = NULL; 364 bp = NULL;
369 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) 365 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
370 bp = at_breakpoint(regs->nip); 366 bp = at_breakpoint(regs->nip);
371 if (bp || (regs->msr & MSR_RI) == 0) 367 if (bp || (regs->msr & MSR_RI) == 0)
372 fromipi = 0; 368 fromipi = 0;
373 369
374 if (!fromipi) { 370 if (!fromipi) {
375 get_output_lock(); 371 get_output_lock();
376 excprint(regs); 372 excprint(regs);
377 if (bp) { 373 if (bp) {
378 printf("cpu 0x%x stopped at breakpoint 0x%x (", 374 printf("cpu 0x%x stopped at breakpoint 0x%x (",
379 cpu, BP_NUM(bp)); 375 cpu, BP_NUM(bp));
380 xmon_print_symbol(regs->nip, " ", ")\n"); 376 xmon_print_symbol(regs->nip, " ", ")\n");
381 } 377 }
382 if ((regs->msr & MSR_RI) == 0) 378 if ((regs->msr & MSR_RI) == 0)
383 printf("WARNING: exception is not recoverable, " 379 printf("WARNING: exception is not recoverable, "
384 "can't continue\n"); 380 "can't continue\n");
385 release_output_lock(); 381 release_output_lock();
386 } 382 }
387 383
388 waiting: 384 waiting:
389 secondary = 1; 385 secondary = 1;
390 while (secondary && !xmon_gate) { 386 while (secondary && !xmon_gate) {
391 if (in_xmon == 0) { 387 if (in_xmon == 0) {
392 if (fromipi) 388 if (fromipi)
393 goto leave; 389 goto leave;
394 secondary = test_and_set_bit(0, &in_xmon); 390 secondary = test_and_set_bit(0, &in_xmon);
395 } 391 }
396 barrier(); 392 barrier();
397 } 393 }
398 394
399 if (!secondary && !xmon_gate) { 395 if (!secondary && !xmon_gate) {
400 /* we are the first cpu to come in */ 396 /* we are the first cpu to come in */
401 /* interrupt other cpu(s) */ 397 /* interrupt other cpu(s) */
402 int ncpus = num_online_cpus(); 398 int ncpus = num_online_cpus();
403 399
404 xmon_owner = cpu; 400 xmon_owner = cpu;
405 mb(); 401 mb();
406 if (ncpus > 1) { 402 if (ncpus > 1) {
407 smp_send_debugger_break(MSG_ALL_BUT_SELF); 403 smp_send_debugger_break(MSG_ALL_BUT_SELF);
408 /* wait for other cpus to come in */ 404 /* wait for other cpus to come in */
409 for (timeout = 100000000; timeout != 0; --timeout) { 405 for (timeout = 100000000; timeout != 0; --timeout) {
410 if (cpus_weight(cpus_in_xmon) >= ncpus) 406 if (cpus_weight(cpus_in_xmon) >= ncpus)
411 break; 407 break;
412 barrier(); 408 barrier();
413 } 409 }
414 } 410 }
415 remove_bpts(); 411 remove_bpts();
416 disable_surveillance(); 412 disable_surveillance();
417 /* for breakpoint or single step, print the current instr. */ 413 /* for breakpoint or single step, print the current instr. */
418 if (bp || TRAP(regs) == 0xd00) 414 if (bp || TRAP(regs) == 0xd00)
419 ppc_inst_dump(regs->nip, 1, 0); 415 ppc_inst_dump(regs->nip, 1, 0);
420 printf("enter ? for help\n"); 416 printf("enter ? for help\n");
421 mb(); 417 mb();
422 xmon_gate = 1; 418 xmon_gate = 1;
423 barrier(); 419 barrier();
424 } 420 }
425 421
426 cmdloop: 422 cmdloop:
427 while (in_xmon) { 423 while (in_xmon) {
428 if (secondary) { 424 if (secondary) {
429 if (cpu == xmon_owner) { 425 if (cpu == xmon_owner) {
430 if (!test_and_set_bit(0, &xmon_taken)) { 426 if (!test_and_set_bit(0, &xmon_taken)) {
431 secondary = 0; 427 secondary = 0;
432 continue; 428 continue;
433 } 429 }
434 /* missed it */ 430 /* missed it */
435 while (cpu == xmon_owner) 431 while (cpu == xmon_owner)
436 barrier(); 432 barrier();
437 } 433 }
438 barrier(); 434 barrier();
439 } else { 435 } else {
440 cmd = cmds(regs); 436 cmd = cmds(regs);
441 if (cmd != 0) { 437 if (cmd != 0) {
442 /* exiting xmon */ 438 /* exiting xmon */
443 insert_bpts(); 439 insert_bpts();
444 xmon_gate = 0; 440 xmon_gate = 0;
445 wmb(); 441 wmb();
446 in_xmon = 0; 442 in_xmon = 0;
447 break; 443 break;
448 } 444 }
449 /* have switched to some other cpu */ 445 /* have switched to some other cpu */
450 secondary = 1; 446 secondary = 1;
451 } 447 }
452 } 448 }
453 leave: 449 leave:
454 cpu_clear(cpu, cpus_in_xmon); 450 cpu_clear(cpu, cpus_in_xmon);
455 xmon_fault_jmp[cpu] = NULL; 451 xmon_fault_jmp[cpu] = NULL;
456 452
457 #else 453 #else
458 /* UP is simple... */ 454 /* UP is simple... */
459 if (in_xmon) { 455 if (in_xmon) {
460 printf("Exception %lx %s in xmon, returning to main loop\n", 456 printf("Exception %lx %s in xmon, returning to main loop\n",
461 regs->trap, getvecname(TRAP(regs))); 457 regs->trap, getvecname(TRAP(regs)));
462 longjmp(xmon_fault_jmp[0], 1); 458 longjmp(xmon_fault_jmp[0], 1);
463 } 459 }
464 if (setjmp(recurse_jmp) == 0) { 460 if (setjmp(recurse_jmp) == 0) {
465 xmon_fault_jmp[0] = recurse_jmp; 461 xmon_fault_jmp[0] = recurse_jmp;
466 in_xmon = 1; 462 in_xmon = 1;
467 463
468 excprint(regs); 464 excprint(regs);
469 bp = at_breakpoint(regs->nip); 465 bp = at_breakpoint(regs->nip);
470 if (bp) { 466 if (bp) {
471 printf("Stopped at breakpoint %x (", BP_NUM(bp)); 467 printf("Stopped at breakpoint %x (", BP_NUM(bp));
472 xmon_print_symbol(regs->nip, " ", ")\n"); 468 xmon_print_symbol(regs->nip, " ", ")\n");
473 } 469 }
474 if ((regs->msr & MSR_RI) == 0) 470 if ((regs->msr & MSR_RI) == 0)
475 printf("WARNING: exception is not recoverable, " 471 printf("WARNING: exception is not recoverable, "
476 "can't continue\n"); 472 "can't continue\n");
477 remove_bpts(); 473 remove_bpts();
478 disable_surveillance(); 474 disable_surveillance();
479 /* for breakpoint or single step, print the current instr. */ 475 /* for breakpoint or single step, print the current instr. */
480 if (bp || TRAP(regs) == 0xd00) 476 if (bp || TRAP(regs) == 0xd00)
481 ppc_inst_dump(regs->nip, 1, 0); 477 ppc_inst_dump(regs->nip, 1, 0);
482 printf("enter ? for help\n"); 478 printf("enter ? for help\n");
483 } 479 }
484 480
485 cmd = cmds(regs); 481 cmd = cmds(regs);
486 482
487 insert_bpts(); 483 insert_bpts();
488 in_xmon = 0; 484 in_xmon = 0;
489 #endif 485 #endif
490 486
491 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) { 487 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
492 bp = at_breakpoint(regs->nip); 488 bp = at_breakpoint(regs->nip);
493 if (bp != NULL) { 489 if (bp != NULL) {
494 int stepped = emulate_step(regs, bp->instr[0]); 490 int stepped = emulate_step(regs, bp->instr[0]);
495 if (stepped == 0) { 491 if (stepped == 0) {
496 regs->nip = (unsigned long) &bp->instr[0]; 492 regs->nip = (unsigned long) &bp->instr[0];
497 atomic_inc(&bp->ref_count); 493 atomic_inc(&bp->ref_count);
498 } else if (stepped < 0) { 494 } else if (stepped < 0) {
499 printf("Couldn't single-step %s instruction\n", 495 printf("Couldn't single-step %s instruction\n",
500 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd")); 496 (IS_RFID(bp->instr[0])? "rfid": "mtmsrd"));
501 } 497 }
502 } 498 }
503 } 499 }
504 500
505 insert_cpu_bpts(); 501 insert_cpu_bpts();
506 502
507 mtmsr(msr); /* restore interrupt enable */ 503 mtmsr(msr); /* restore interrupt enable */
508 504
509 return cmd != 'X'; 505 return cmd != 'X';
510 } 506 }
511 507
512 int xmon(struct pt_regs *excp) 508 int xmon(struct pt_regs *excp)
513 { 509 {
514 struct pt_regs regs; 510 struct pt_regs regs;
515 511
516 if (excp == NULL) { 512 if (excp == NULL) {
517 xmon_save_regs(&regs); 513 xmon_save_regs(&regs);
518 excp = &regs; 514 excp = &regs;
519 } 515 }
520 return xmon_core(excp, 0); 516 return xmon_core(excp, 0);
521 } 517 }
522 EXPORT_SYMBOL(xmon); 518 EXPORT_SYMBOL(xmon);
523 519
524 irqreturn_t 520 irqreturn_t
525 xmon_irq(int irq, void *d, struct pt_regs *regs) 521 xmon_irq(int irq, void *d, struct pt_regs *regs)
526 { 522 {
527 unsigned long flags; 523 unsigned long flags;
528 local_irq_save(flags); 524 local_irq_save(flags);
529 printf("Keyboard interrupt\n"); 525 printf("Keyboard interrupt\n");
530 xmon(regs); 526 xmon(regs);
531 local_irq_restore(flags); 527 local_irq_restore(flags);
532 return IRQ_HANDLED; 528 return IRQ_HANDLED;
533 } 529 }
534 530
535 int xmon_bpt(struct pt_regs *regs) 531 int xmon_bpt(struct pt_regs *regs)
536 { 532 {
537 struct bpt *bp; 533 struct bpt *bp;
538 unsigned long offset; 534 unsigned long offset;
539 535
540 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 536 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
541 return 0; 537 return 0;
542 538
543 /* Are we at the trap at bp->instr[1] for some bp? */ 539 /* Are we at the trap at bp->instr[1] for some bp? */
544 bp = in_breakpoint_table(regs->nip, &offset); 540 bp = in_breakpoint_table(regs->nip, &offset);
545 if (bp != NULL && offset == 4) { 541 if (bp != NULL && offset == 4) {
546 regs->nip = bp->address + 4; 542 regs->nip = bp->address + 4;
547 atomic_dec(&bp->ref_count); 543 atomic_dec(&bp->ref_count);
548 return 1; 544 return 1;
549 } 545 }
550 546
551 /* Are we at a breakpoint? */ 547 /* Are we at a breakpoint? */
552 bp = at_breakpoint(regs->nip); 548 bp = at_breakpoint(regs->nip);
553 if (!bp) 549 if (!bp)
554 return 0; 550 return 0;
555 551
556 xmon_core(regs, 0); 552 xmon_core(regs, 0);
557 553
558 return 1; 554 return 1;
559 } 555 }
560 556
561 int xmon_sstep(struct pt_regs *regs) 557 int xmon_sstep(struct pt_regs *regs)
562 { 558 {
563 if (user_mode(regs)) 559 if (user_mode(regs))
564 return 0; 560 return 0;
565 xmon_core(regs, 0); 561 xmon_core(regs, 0);
566 return 1; 562 return 1;
567 } 563 }
568 564
569 int xmon_dabr_match(struct pt_regs *regs) 565 int xmon_dabr_match(struct pt_regs *regs)
570 { 566 {
571 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 567 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
572 return 0; 568 return 0;
573 if (dabr.enabled == 0) 569 if (dabr.enabled == 0)
574 return 0; 570 return 0;
575 xmon_core(regs, 0); 571 xmon_core(regs, 0);
576 return 1; 572 return 1;
577 } 573 }
578 574
579 int xmon_iabr_match(struct pt_regs *regs) 575 int xmon_iabr_match(struct pt_regs *regs)
580 { 576 {
581 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF)) 577 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
582 return 0; 578 return 0;
583 if (iabr == 0) 579 if (iabr == 0)
584 return 0; 580 return 0;
585 xmon_core(regs, 0); 581 xmon_core(regs, 0);
586 return 1; 582 return 1;
587 } 583 }
588 584
589 int xmon_ipi(struct pt_regs *regs) 585 int xmon_ipi(struct pt_regs *regs)
590 { 586 {
591 #ifdef CONFIG_SMP 587 #ifdef CONFIG_SMP
592 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon)) 588 if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
593 xmon_core(regs, 1); 589 xmon_core(regs, 1);
594 #endif 590 #endif
595 return 0; 591 return 0;
596 } 592 }
597 593
598 int xmon_fault_handler(struct pt_regs *regs) 594 int xmon_fault_handler(struct pt_regs *regs)
599 { 595 {
600 struct bpt *bp; 596 struct bpt *bp;
601 unsigned long offset; 597 unsigned long offset;
602 598
603 if (in_xmon && catch_memory_errors) 599 if (in_xmon && catch_memory_errors)
604 handle_fault(regs); /* doesn't return */ 600 handle_fault(regs); /* doesn't return */
605 601
606 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) { 602 if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
607 bp = in_breakpoint_table(regs->nip, &offset); 603 bp = in_breakpoint_table(regs->nip, &offset);
608 if (bp != NULL) { 604 if (bp != NULL) {
609 regs->nip = bp->address + offset; 605 regs->nip = bp->address + offset;
610 atomic_dec(&bp->ref_count); 606 atomic_dec(&bp->ref_count);
611 } 607 }
612 } 608 }
613 609
614 return 0; 610 return 0;
615 } 611 }
616 612
617 static struct bpt *at_breakpoint(unsigned long pc) 613 static struct bpt *at_breakpoint(unsigned long pc)
618 { 614 {
619 int i; 615 int i;
620 struct bpt *bp; 616 struct bpt *bp;
621 617
622 bp = bpts; 618 bp = bpts;
623 for (i = 0; i < NBPTS; ++i, ++bp) 619 for (i = 0; i < NBPTS; ++i, ++bp)
624 if (bp->enabled && pc == bp->address) 620 if (bp->enabled && pc == bp->address)
625 return bp; 621 return bp;
626 return NULL; 622 return NULL;
627 } 623 }
628 624
629 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) 625 static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp)
630 { 626 {
631 unsigned long off; 627 unsigned long off;
632 628
633 off = nip - (unsigned long) bpts; 629 off = nip - (unsigned long) bpts;
634 if (off >= sizeof(bpts)) 630 if (off >= sizeof(bpts))
635 return NULL; 631 return NULL;
636 off %= sizeof(struct bpt); 632 off %= sizeof(struct bpt);
637 if (off != offsetof(struct bpt, instr[0]) 633 if (off != offsetof(struct bpt, instr[0])
638 && off != offsetof(struct bpt, instr[1])) 634 && off != offsetof(struct bpt, instr[1]))
639 return NULL; 635 return NULL;
640 *offp = off - offsetof(struct bpt, instr[0]); 636 *offp = off - offsetof(struct bpt, instr[0]);
641 return (struct bpt *) (nip - off); 637 return (struct bpt *) (nip - off);
642 } 638 }
643 639
644 static struct bpt *new_breakpoint(unsigned long a) 640 static struct bpt *new_breakpoint(unsigned long a)
645 { 641 {
646 struct bpt *bp; 642 struct bpt *bp;
647 643
648 a &= ~3UL; 644 a &= ~3UL;
649 bp = at_breakpoint(a); 645 bp = at_breakpoint(a);
650 if (bp) 646 if (bp)
651 return bp; 647 return bp;
652 648
653 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 649 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
654 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { 650 if (!bp->enabled && atomic_read(&bp->ref_count) == 0) {
655 bp->address = a; 651 bp->address = a;
656 bp->instr[1] = bpinstr; 652 bp->instr[1] = bpinstr;
657 store_inst(&bp->instr[1]); 653 store_inst(&bp->instr[1]);
658 return bp; 654 return bp;
659 } 655 }
660 } 656 }
661 657
662 printf("Sorry, no free breakpoints. Please clear one first.\n"); 658 printf("Sorry, no free breakpoints. Please clear one first.\n");
663 return NULL; 659 return NULL;
664 } 660 }
665 661
666 static void insert_bpts(void) 662 static void insert_bpts(void)
667 { 663 {
668 int i; 664 int i;
669 struct bpt *bp; 665 struct bpt *bp;
670 666
671 bp = bpts; 667 bp = bpts;
672 for (i = 0; i < NBPTS; ++i, ++bp) { 668 for (i = 0; i < NBPTS; ++i, ++bp) {
673 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0) 669 if ((bp->enabled & (BP_TRAP|BP_IABR)) == 0)
674 continue; 670 continue;
675 if (mread(bp->address, &bp->instr[0], 4) != 4) { 671 if (mread(bp->address, &bp->instr[0], 4) != 4) {
676 printf("Couldn't read instruction at %lx, " 672 printf("Couldn't read instruction at %lx, "
677 "disabling breakpoint there\n", bp->address); 673 "disabling breakpoint there\n", bp->address);
678 bp->enabled = 0; 674 bp->enabled = 0;
679 continue; 675 continue;
680 } 676 }
681 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) { 677 if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) {
682 printf("Breakpoint at %lx is on an mtmsrd or rfid " 678 printf("Breakpoint at %lx is on an mtmsrd or rfid "
683 "instruction, disabling it\n", bp->address); 679 "instruction, disabling it\n", bp->address);
684 bp->enabled = 0; 680 bp->enabled = 0;
685 continue; 681 continue;
686 } 682 }
687 store_inst(&bp->instr[0]); 683 store_inst(&bp->instr[0]);
688 if (bp->enabled & BP_IABR) 684 if (bp->enabled & BP_IABR)
689 continue; 685 continue;
690 if (mwrite(bp->address, &bpinstr, 4) != 4) { 686 if (mwrite(bp->address, &bpinstr, 4) != 4) {
691 printf("Couldn't write instruction at %lx, " 687 printf("Couldn't write instruction at %lx, "
692 "disabling breakpoint there\n", bp->address); 688 "disabling breakpoint there\n", bp->address);
693 bp->enabled &= ~BP_TRAP; 689 bp->enabled &= ~BP_TRAP;
694 continue; 690 continue;
695 } 691 }
696 store_inst((void *)bp->address); 692 store_inst((void *)bp->address);
697 } 693 }
698 } 694 }
699 695
700 static void insert_cpu_bpts(void) 696 static void insert_cpu_bpts(void)
701 { 697 {
702 if (dabr.enabled) 698 if (dabr.enabled)
703 set_dabr(dabr.address | (dabr.enabled & 7)); 699 set_dabr(dabr.address | (dabr.enabled & 7));
704 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 700 if (iabr && cpu_has_feature(CPU_FTR_IABR))
705 mtspr(SPRN_IABR, iabr->address 701 mtspr(SPRN_IABR, iabr->address
706 | (iabr->enabled & (BP_IABR|BP_IABR_TE))); 702 | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
707 } 703 }
708 704
709 static void remove_bpts(void) 705 static void remove_bpts(void)
710 { 706 {
711 int i; 707 int i;
712 struct bpt *bp; 708 struct bpt *bp;
713 unsigned instr; 709 unsigned instr;
714 710
715 bp = bpts; 711 bp = bpts;
716 for (i = 0; i < NBPTS; ++i, ++bp) { 712 for (i = 0; i < NBPTS; ++i, ++bp) {
717 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP) 713 if ((bp->enabled & (BP_TRAP|BP_IABR)) != BP_TRAP)
718 continue; 714 continue;
719 if (mread(bp->address, &instr, 4) == 4 715 if (mread(bp->address, &instr, 4) == 4
720 && instr == bpinstr 716 && instr == bpinstr
721 && mwrite(bp->address, &bp->instr, 4) != 4) 717 && mwrite(bp->address, &bp->instr, 4) != 4)
722 printf("Couldn't remove breakpoint at %lx\n", 718 printf("Couldn't remove breakpoint at %lx\n",
723 bp->address); 719 bp->address);
724 else 720 else
725 store_inst((void *)bp->address); 721 store_inst((void *)bp->address);
726 } 722 }
727 } 723 }
728 724
729 static void remove_cpu_bpts(void) 725 static void remove_cpu_bpts(void)
730 { 726 {
731 set_dabr(0); 727 set_dabr(0);
732 if (cpu_has_feature(CPU_FTR_IABR)) 728 if (cpu_has_feature(CPU_FTR_IABR))
733 mtspr(SPRN_IABR, 0); 729 mtspr(SPRN_IABR, 0);
734 } 730 }
735 731
736 /* Command interpreting routine */ 732 /* Command interpreting routine */
737 static char *last_cmd; 733 static char *last_cmd;
738 734
739 static int 735 static int
740 cmds(struct pt_regs *excp) 736 cmds(struct pt_regs *excp)
741 { 737 {
742 int cmd = 0; 738 int cmd = 0;
743 739
744 last_cmd = NULL; 740 last_cmd = NULL;
745 xmon_regs = excp; 741 xmon_regs = excp;
746 for(;;) { 742 for(;;) {
747 #ifdef CONFIG_SMP 743 #ifdef CONFIG_SMP
748 printf("%x:", smp_processor_id()); 744 printf("%x:", smp_processor_id());
749 #endif /* CONFIG_SMP */ 745 #endif /* CONFIG_SMP */
750 printf("mon> "); 746 printf("mon> ");
751 fflush(stdout);
752 flush_input(); 747 flush_input();
753 termch = 0; 748 termch = 0;
754 cmd = skipbl(); 749 cmd = skipbl();
755 if( cmd == '\n' ) { 750 if( cmd == '\n' ) {
756 if (last_cmd == NULL) 751 if (last_cmd == NULL)
757 continue; 752 continue;
758 take_input(last_cmd); 753 take_input(last_cmd);
759 last_cmd = NULL; 754 last_cmd = NULL;
760 cmd = inchar(); 755 cmd = inchar();
761 } 756 }
762 switch (cmd) { 757 switch (cmd) {
763 case 'm': 758 case 'm':
764 cmd = inchar(); 759 cmd = inchar();
765 switch (cmd) { 760 switch (cmd) {
766 case 'm': 761 case 'm':
767 case 's': 762 case 's':
768 case 'd': 763 case 'd':
769 memops(cmd); 764 memops(cmd);
770 break; 765 break;
771 case 'l': 766 case 'l':
772 memlocate(); 767 memlocate();
773 break; 768 break;
774 case 'z': 769 case 'z':
775 memzcan(); 770 memzcan();
776 break; 771 break;
777 case 'i': 772 case 'i':
778 show_mem(); 773 show_mem();
779 break; 774 break;
780 default: 775 default:
781 termch = cmd; 776 termch = cmd;
782 memex(); 777 memex();
783 } 778 }
784 break; 779 break;
785 case 'd': 780 case 'd':
786 dump(); 781 dump();
787 break; 782 break;
788 case 'l': 783 case 'l':
789 symbol_lookup(); 784 symbol_lookup();
790 break; 785 break;
791 case 'r': 786 case 'r':
792 prregs(excp); /* print regs */ 787 prregs(excp); /* print regs */
793 break; 788 break;
794 case 'e': 789 case 'e':
795 excprint(excp); 790 excprint(excp);
796 break; 791 break;
797 case 'S': 792 case 'S':
798 super_regs(); 793 super_regs();
799 break; 794 break;
800 case 't': 795 case 't':
801 backtrace(excp); 796 backtrace(excp);
802 break; 797 break;
803 case 'f': 798 case 'f':
804 cacheflush(); 799 cacheflush();
805 break; 800 break;
806 case 's': 801 case 's':
807 if (do_step(excp)) 802 if (do_step(excp))
808 return cmd; 803 return cmd;
809 break; 804 break;
810 case 'x': 805 case 'x':
811 case 'X': 806 case 'X':
812 case EOF: 807 case EOF:
813 return cmd; 808 return cmd;
814 case '?': 809 case '?':
815 printf(help_string); 810 printf(help_string);
816 break; 811 break;
817 case 'b': 812 case 'b':
818 bpt_cmds(); 813 bpt_cmds();
819 break; 814 break;
820 case 'C': 815 case 'C':
821 csum(); 816 csum();
822 break; 817 break;
823 case 'c': 818 case 'c':
824 if (cpu_cmd()) 819 if (cpu_cmd())
825 return 0; 820 return 0;
826 break; 821 break;
827 case 'z': 822 case 'z':
828 bootcmds(); 823 bootcmds();
829 break; 824 break;
830 case 'p': 825 case 'p':
831 proccall(); 826 proccall();
832 break; 827 break;
833 #ifdef CONFIG_PPC_STD_MMU 828 #ifdef CONFIG_PPC_STD_MMU
834 case 'u': 829 case 'u':
835 dump_segments(); 830 dump_segments();
836 break; 831 break;
837 #endif 832 #endif
838 default: 833 default:
839 printf("Unrecognized command: "); 834 printf("Unrecognized command: ");
840 do { 835 do {
841 if (' ' < cmd && cmd <= '~') 836 if (' ' < cmd && cmd <= '~')
842 putchar(cmd); 837 putchar(cmd);
843 else 838 else
844 printf("\\x%x", cmd); 839 printf("\\x%x", cmd);
845 cmd = inchar(); 840 cmd = inchar();
846 } while (cmd != '\n'); 841 } while (cmd != '\n');
847 printf(" (type ? for help)\n"); 842 printf(" (type ? for help)\n");
848 break; 843 break;
849 } 844 }
850 } 845 }
851 } 846 }
852 847
853 /* 848 /*
854 * Step a single instruction. 849 * Step a single instruction.
855 * Some instructions we emulate, others we execute with MSR_SE set. 850 * Some instructions we emulate, others we execute with MSR_SE set.
856 */ 851 */
857 static int do_step(struct pt_regs *regs) 852 static int do_step(struct pt_regs *regs)
858 { 853 {
859 unsigned int instr; 854 unsigned int instr;
860 int stepped; 855 int stepped;
861 856
862 /* check we are in 64-bit kernel mode, translation enabled */ 857 /* check we are in 64-bit kernel mode, translation enabled */
863 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) { 858 if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
864 if (mread(regs->nip, &instr, 4) == 4) { 859 if (mread(regs->nip, &instr, 4) == 4) {
865 stepped = emulate_step(regs, instr); 860 stepped = emulate_step(regs, instr);
866 if (stepped < 0) { 861 if (stepped < 0) {
867 printf("Couldn't single-step %s instruction\n", 862 printf("Couldn't single-step %s instruction\n",
868 (IS_RFID(instr)? "rfid": "mtmsrd")); 863 (IS_RFID(instr)? "rfid": "mtmsrd"));
869 return 0; 864 return 0;
870 } 865 }
871 if (stepped > 0) { 866 if (stepped > 0) {
872 regs->trap = 0xd00 | (regs->trap & 1); 867 regs->trap = 0xd00 | (regs->trap & 1);
873 printf("stepped to "); 868 printf("stepped to ");
874 xmon_print_symbol(regs->nip, " ", "\n"); 869 xmon_print_symbol(regs->nip, " ", "\n");
875 ppc_inst_dump(regs->nip, 1, 0); 870 ppc_inst_dump(regs->nip, 1, 0);
876 return 0; 871 return 0;
877 } 872 }
878 } 873 }
879 } 874 }
880 regs->msr |= MSR_SE; 875 regs->msr |= MSR_SE;
881 return 1; 876 return 1;
882 } 877 }
883 878
884 static void bootcmds(void) 879 static void bootcmds(void)
885 { 880 {
886 int cmd; 881 int cmd;
887 882
888 cmd = inchar(); 883 cmd = inchar();
889 if (cmd == 'r') 884 if (cmd == 'r')
890 ppc_md.restart(NULL); 885 ppc_md.restart(NULL);
891 else if (cmd == 'h') 886 else if (cmd == 'h')
892 ppc_md.halt(); 887 ppc_md.halt();
893 else if (cmd == 'p') 888 else if (cmd == 'p')
894 ppc_md.power_off(); 889 ppc_md.power_off();
895 } 890 }
896 891
897 static int cpu_cmd(void) 892 static int cpu_cmd(void)
898 { 893 {
899 #ifdef CONFIG_SMP 894 #ifdef CONFIG_SMP
900 unsigned long cpu; 895 unsigned long cpu;
901 int timeout; 896 int timeout;
902 int count; 897 int count;
903 898
904 if (!scanhex(&cpu)) { 899 if (!scanhex(&cpu)) {
905 /* print cpus waiting or in xmon */ 900 /* print cpus waiting or in xmon */
906 printf("cpus stopped:"); 901 printf("cpus stopped:");
907 count = 0; 902 count = 0;
908 for (cpu = 0; cpu < NR_CPUS; ++cpu) { 903 for (cpu = 0; cpu < NR_CPUS; ++cpu) {
909 if (cpu_isset(cpu, cpus_in_xmon)) { 904 if (cpu_isset(cpu, cpus_in_xmon)) {
910 if (count == 0) 905 if (count == 0)
911 printf(" %x", cpu); 906 printf(" %x", cpu);
912 ++count; 907 ++count;
913 } else { 908 } else {
914 if (count > 1) 909 if (count > 1)
915 printf("-%x", cpu - 1); 910 printf("-%x", cpu - 1);
916 count = 0; 911 count = 0;
917 } 912 }
918 } 913 }
919 if (count > 1) 914 if (count > 1)
920 printf("-%x", NR_CPUS - 1); 915 printf("-%x", NR_CPUS - 1);
921 printf("\n"); 916 printf("\n");
922 return 0; 917 return 0;
923 } 918 }
924 /* try to switch to cpu specified */ 919 /* try to switch to cpu specified */
925 if (!cpu_isset(cpu, cpus_in_xmon)) { 920 if (!cpu_isset(cpu, cpus_in_xmon)) {
926 printf("cpu 0x%x isn't in xmon\n", cpu); 921 printf("cpu 0x%x isn't in xmon\n", cpu);
927 return 0; 922 return 0;
928 } 923 }
929 xmon_taken = 0; 924 xmon_taken = 0;
930 mb(); 925 mb();
931 xmon_owner = cpu; 926 xmon_owner = cpu;
932 timeout = 10000000; 927 timeout = 10000000;
933 while (!xmon_taken) { 928 while (!xmon_taken) {
934 if (--timeout == 0) { 929 if (--timeout == 0) {
935 if (test_and_set_bit(0, &xmon_taken)) 930 if (test_and_set_bit(0, &xmon_taken))
936 break; 931 break;
937 /* take control back */ 932 /* take control back */
938 mb(); 933 mb();
939 xmon_owner = smp_processor_id(); 934 xmon_owner = smp_processor_id();
940 printf("cpu %u didn't take control\n", cpu); 935 printf("cpu %u didn't take control\n", cpu);
941 return 0; 936 return 0;
942 } 937 }
943 barrier(); 938 barrier();
944 } 939 }
945 return 1; 940 return 1;
946 #else 941 #else
947 return 0; 942 return 0;
948 #endif /* CONFIG_SMP */ 943 #endif /* CONFIG_SMP */
949 } 944 }
950 945
951 static unsigned short fcstab[256] = { 946 static unsigned short fcstab[256] = {
952 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 947 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
953 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 948 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
954 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 949 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
955 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 950 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
956 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 951 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
957 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 952 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
958 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 953 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
959 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 954 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
960 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 955 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
961 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 956 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
962 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 957 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
963 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 958 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
964 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 959 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
965 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 960 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
966 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 961 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
967 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 962 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
968 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 963 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
969 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 964 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
970 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 965 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
971 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 966 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
972 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 967 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
973 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 968 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
974 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 969 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
975 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 970 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
976 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 971 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
977 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 972 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
978 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 973 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
979 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 974 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
980 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 975 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
981 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 976 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
982 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 977 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
983 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 978 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
984 }; 979 };
985 980
986 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) 981 #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
987 982
988 static void 983 static void
989 csum(void) 984 csum(void)
990 { 985 {
991 unsigned int i; 986 unsigned int i;
992 unsigned short fcs; 987 unsigned short fcs;
993 unsigned char v; 988 unsigned char v;
994 989
995 if (!scanhex(&adrs)) 990 if (!scanhex(&adrs))
996 return; 991 return;
997 if (!scanhex(&ncsum)) 992 if (!scanhex(&ncsum))
998 return; 993 return;
999 fcs = 0xffff; 994 fcs = 0xffff;
1000 for (i = 0; i < ncsum; ++i) { 995 for (i = 0; i < ncsum; ++i) {
1001 if (mread(adrs+i, &v, 1) == 0) { 996 if (mread(adrs+i, &v, 1) == 0) {
1002 printf("csum stopped at %x\n", adrs+i); 997 printf("csum stopped at %x\n", adrs+i);
1003 break; 998 break;
1004 } 999 }
1005 fcs = FCS(fcs, v); 1000 fcs = FCS(fcs, v);
1006 } 1001 }
1007 printf("%x\n", fcs); 1002 printf("%x\n", fcs);
1008 } 1003 }
1009 1004
1010 /* 1005 /*
1011 * Check if this is a suitable place to put a breakpoint. 1006 * Check if this is a suitable place to put a breakpoint.
1012 */ 1007 */
1013 static long check_bp_loc(unsigned long addr) 1008 static long check_bp_loc(unsigned long addr)
1014 { 1009 {
1015 unsigned int instr; 1010 unsigned int instr;
1016 1011
1017 addr &= ~3; 1012 addr &= ~3;
1018 if (addr < KERNELBASE) { 1013 if (addr < KERNELBASE) {
1019 printf("Breakpoints may only be placed at kernel addresses\n"); 1014 printf("Breakpoints may only be placed at kernel addresses\n");
1020 return 0; 1015 return 0;
1021 } 1016 }
1022 if (!mread(addr, &instr, sizeof(instr))) { 1017 if (!mread(addr, &instr, sizeof(instr))) {
1023 printf("Can't read instruction at address %lx\n", addr); 1018 printf("Can't read instruction at address %lx\n", addr);
1024 return 0; 1019 return 0;
1025 } 1020 }
1026 if (IS_MTMSRD(instr) || IS_RFID(instr)) { 1021 if (IS_MTMSRD(instr) || IS_RFID(instr)) {
1027 printf("Breakpoints may not be placed on mtmsrd or rfid " 1022 printf("Breakpoints may not be placed on mtmsrd or rfid "
1028 "instructions\n"); 1023 "instructions\n");
1029 return 0; 1024 return 0;
1030 } 1025 }
1031 return 1; 1026 return 1;
1032 } 1027 }
1033 1028
1034 static char *breakpoint_help_string = 1029 static char *breakpoint_help_string =
1035 "Breakpoint command usage:\n" 1030 "Breakpoint command usage:\n"
1036 "b show breakpoints\n" 1031 "b show breakpoints\n"
1037 "b <addr> [cnt] set breakpoint at given instr addr\n" 1032 "b <addr> [cnt] set breakpoint at given instr addr\n"
1038 "bc clear all breakpoints\n" 1033 "bc clear all breakpoints\n"
1039 "bc <n/addr> clear breakpoint number n or at addr\n" 1034 "bc <n/addr> clear breakpoint number n or at addr\n"
1040 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" 1035 "bi <addr> [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n"
1041 "bd <addr> [cnt] set hardware data breakpoint\n" 1036 "bd <addr> [cnt] set hardware data breakpoint\n"
1042 ""; 1037 "";
1043 1038
1044 static void 1039 static void
1045 bpt_cmds(void) 1040 bpt_cmds(void)
1046 { 1041 {
1047 int cmd; 1042 int cmd;
1048 unsigned long a; 1043 unsigned long a;
1049 int mode, i; 1044 int mode, i;
1050 struct bpt *bp; 1045 struct bpt *bp;
1051 const char badaddr[] = "Only kernel addresses are permitted " 1046 const char badaddr[] = "Only kernel addresses are permitted "
1052 "for breakpoints\n"; 1047 "for breakpoints\n";
1053 1048
1054 cmd = inchar(); 1049 cmd = inchar();
1055 switch (cmd) { 1050 switch (cmd) {
1056 #ifndef CONFIG_8xx 1051 #ifndef CONFIG_8xx
1057 case 'd': /* bd - hardware data breakpoint */ 1052 case 'd': /* bd - hardware data breakpoint */
1058 mode = 7; 1053 mode = 7;
1059 cmd = inchar(); 1054 cmd = inchar();
1060 if (cmd == 'r') 1055 if (cmd == 'r')
1061 mode = 5; 1056 mode = 5;
1062 else if (cmd == 'w') 1057 else if (cmd == 'w')
1063 mode = 6; 1058 mode = 6;
1064 else 1059 else
1065 termch = cmd; 1060 termch = cmd;
1066 dabr.address = 0; 1061 dabr.address = 0;
1067 dabr.enabled = 0; 1062 dabr.enabled = 0;
1068 if (scanhex(&dabr.address)) { 1063 if (scanhex(&dabr.address)) {
1069 if (dabr.address < KERNELBASE) { 1064 if (dabr.address < KERNELBASE) {
1070 printf(badaddr); 1065 printf(badaddr);
1071 break; 1066 break;
1072 } 1067 }
1073 dabr.address &= ~7; 1068 dabr.address &= ~7;
1074 dabr.enabled = mode | BP_DABR; 1069 dabr.enabled = mode | BP_DABR;
1075 } 1070 }
1076 break; 1071 break;
1077 1072
1078 case 'i': /* bi - hardware instr breakpoint */ 1073 case 'i': /* bi - hardware instr breakpoint */
1079 if (!cpu_has_feature(CPU_FTR_IABR)) { 1074 if (!cpu_has_feature(CPU_FTR_IABR)) {
1080 printf("Hardware instruction breakpoint " 1075 printf("Hardware instruction breakpoint "
1081 "not supported on this cpu\n"); 1076 "not supported on this cpu\n");
1082 break; 1077 break;
1083 } 1078 }
1084 if (iabr) { 1079 if (iabr) {
1085 iabr->enabled &= ~(BP_IABR | BP_IABR_TE); 1080 iabr->enabled &= ~(BP_IABR | BP_IABR_TE);
1086 iabr = NULL; 1081 iabr = NULL;
1087 } 1082 }
1088 if (!scanhex(&a)) 1083 if (!scanhex(&a))
1089 break; 1084 break;
1090 if (!check_bp_loc(a)) 1085 if (!check_bp_loc(a))
1091 break; 1086 break;
1092 bp = new_breakpoint(a); 1087 bp = new_breakpoint(a);
1093 if (bp != NULL) { 1088 if (bp != NULL) {
1094 bp->enabled |= BP_IABR | BP_IABR_TE; 1089 bp->enabled |= BP_IABR | BP_IABR_TE;
1095 iabr = bp; 1090 iabr = bp;
1096 } 1091 }
1097 break; 1092 break;
1098 #endif 1093 #endif
1099 1094
1100 case 'c': 1095 case 'c':
1101 if (!scanhex(&a)) { 1096 if (!scanhex(&a)) {
1102 /* clear all breakpoints */ 1097 /* clear all breakpoints */
1103 for (i = 0; i < NBPTS; ++i) 1098 for (i = 0; i < NBPTS; ++i)
1104 bpts[i].enabled = 0; 1099 bpts[i].enabled = 0;
1105 iabr = NULL; 1100 iabr = NULL;
1106 dabr.enabled = 0; 1101 dabr.enabled = 0;
1107 printf("All breakpoints cleared\n"); 1102 printf("All breakpoints cleared\n");
1108 break; 1103 break;
1109 } 1104 }
1110 1105
1111 if (a <= NBPTS && a >= 1) { 1106 if (a <= NBPTS && a >= 1) {
1112 /* assume a breakpoint number */ 1107 /* assume a breakpoint number */
1113 bp = &bpts[a-1]; /* bp nums are 1 based */ 1108 bp = &bpts[a-1]; /* bp nums are 1 based */
1114 } else { 1109 } else {
1115 /* assume a breakpoint address */ 1110 /* assume a breakpoint address */
1116 bp = at_breakpoint(a); 1111 bp = at_breakpoint(a);
1117 if (bp == 0) { 1112 if (bp == 0) {
1118 printf("No breakpoint at %x\n", a); 1113 printf("No breakpoint at %x\n", a);
1119 break; 1114 break;
1120 } 1115 }
1121 } 1116 }
1122 1117
1123 printf("Cleared breakpoint %x (", BP_NUM(bp)); 1118 printf("Cleared breakpoint %x (", BP_NUM(bp));
1124 xmon_print_symbol(bp->address, " ", ")\n"); 1119 xmon_print_symbol(bp->address, " ", ")\n");
1125 bp->enabled = 0; 1120 bp->enabled = 0;
1126 break; 1121 break;
1127 1122
1128 default: 1123 default:
1129 termch = cmd; 1124 termch = cmd;
1130 cmd = skipbl(); 1125 cmd = skipbl();
1131 if (cmd == '?') { 1126 if (cmd == '?') {
1132 printf(breakpoint_help_string); 1127 printf(breakpoint_help_string);
1133 break; 1128 break;
1134 } 1129 }
1135 termch = cmd; 1130 termch = cmd;
1136 if (!scanhex(&a)) { 1131 if (!scanhex(&a)) {
1137 /* print all breakpoints */ 1132 /* print all breakpoints */
1138 printf(" type address\n"); 1133 printf(" type address\n");
1139 if (dabr.enabled) { 1134 if (dabr.enabled) {
1140 printf(" data "REG" [", dabr.address); 1135 printf(" data "REG" [", dabr.address);
1141 if (dabr.enabled & 1) 1136 if (dabr.enabled & 1)
1142 printf("r"); 1137 printf("r");
1143 if (dabr.enabled & 2) 1138 if (dabr.enabled & 2)
1144 printf("w"); 1139 printf("w");
1145 printf("]\n"); 1140 printf("]\n");
1146 } 1141 }
1147 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { 1142 for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
1148 if (!bp->enabled) 1143 if (!bp->enabled)
1149 continue; 1144 continue;
1150 printf("%2x %s ", BP_NUM(bp), 1145 printf("%2x %s ", BP_NUM(bp),
1151 (bp->enabled & BP_IABR)? "inst": "trap"); 1146 (bp->enabled & BP_IABR)? "inst": "trap");
1152 xmon_print_symbol(bp->address, " ", "\n"); 1147 xmon_print_symbol(bp->address, " ", "\n");
1153 } 1148 }
1154 break; 1149 break;
1155 } 1150 }
1156 1151
1157 if (!check_bp_loc(a)) 1152 if (!check_bp_loc(a))
1158 break; 1153 break;
1159 bp = new_breakpoint(a); 1154 bp = new_breakpoint(a);
1160 if (bp != NULL) 1155 if (bp != NULL)
1161 bp->enabled |= BP_TRAP; 1156 bp->enabled |= BP_TRAP;
1162 break; 1157 break;
1163 } 1158 }
1164 } 1159 }
1165 1160
1166 /* Very cheap human name for vector lookup. */ 1161 /* Very cheap human name for vector lookup. */
1167 static 1162 static
1168 const char *getvecname(unsigned long vec) 1163 const char *getvecname(unsigned long vec)
1169 { 1164 {
1170 char *ret; 1165 char *ret;
1171 1166
1172 switch (vec) { 1167 switch (vec) {
1173 case 0x100: ret = "(System Reset)"; break; 1168 case 0x100: ret = "(System Reset)"; break;
1174 case 0x200: ret = "(Machine Check)"; break; 1169 case 0x200: ret = "(Machine Check)"; break;
1175 case 0x300: ret = "(Data Access)"; break; 1170 case 0x300: ret = "(Data Access)"; break;
1176 case 0x380: ret = "(Data SLB Access)"; break; 1171 case 0x380: ret = "(Data SLB Access)"; break;
1177 case 0x400: ret = "(Instruction Access)"; break; 1172 case 0x400: ret = "(Instruction Access)"; break;
1178 case 0x480: ret = "(Instruction SLB Access)"; break; 1173 case 0x480: ret = "(Instruction SLB Access)"; break;
1179 case 0x500: ret = "(Hardware Interrupt)"; break; 1174 case 0x500: ret = "(Hardware Interrupt)"; break;
1180 case 0x600: ret = "(Alignment)"; break; 1175 case 0x600: ret = "(Alignment)"; break;
1181 case 0x700: ret = "(Program Check)"; break; 1176 case 0x700: ret = "(Program Check)"; break;
1182 case 0x800: ret = "(FPU Unavailable)"; break; 1177 case 0x800: ret = "(FPU Unavailable)"; break;
1183 case 0x900: ret = "(Decrementer)"; break; 1178 case 0x900: ret = "(Decrementer)"; break;
1184 case 0xc00: ret = "(System Call)"; break; 1179 case 0xc00: ret = "(System Call)"; break;
1185 case 0xd00: ret = "(Single Step)"; break; 1180 case 0xd00: ret = "(Single Step)"; break;
1186 case 0xf00: ret = "(Performance Monitor)"; break; 1181 case 0xf00: ret = "(Performance Monitor)"; break;
1187 case 0xf20: ret = "(Altivec Unavailable)"; break; 1182 case 0xf20: ret = "(Altivec Unavailable)"; break;
1188 case 0x1300: ret = "(Instruction Breakpoint)"; break; 1183 case 0x1300: ret = "(Instruction Breakpoint)"; break;
1189 default: ret = ""; 1184 default: ret = "";
1190 } 1185 }
1191 return ret; 1186 return ret;
1192 } 1187 }
1193 1188
1194 static void get_function_bounds(unsigned long pc, unsigned long *startp, 1189 static void get_function_bounds(unsigned long pc, unsigned long *startp,
1195 unsigned long *endp) 1190 unsigned long *endp)
1196 { 1191 {
1197 unsigned long size, offset; 1192 unsigned long size, offset;
1198 const char *name; 1193 const char *name;
1199 char *modname; 1194 char *modname;
1200 1195
1201 *startp = *endp = 0; 1196 *startp = *endp = 0;
1202 if (pc == 0) 1197 if (pc == 0)
1203 return; 1198 return;
1204 if (setjmp(bus_error_jmp) == 0) { 1199 if (setjmp(bus_error_jmp) == 0) {
1205 catch_memory_errors = 1; 1200 catch_memory_errors = 1;
1206 sync(); 1201 sync();
1207 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr); 1202 name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
1208 if (name != NULL) { 1203 if (name != NULL) {
1209 *startp = pc - offset; 1204 *startp = pc - offset;
1210 *endp = pc - offset + size; 1205 *endp = pc - offset + size;
1211 } 1206 }
1212 sync(); 1207 sync();
1213 } 1208 }
1214 catch_memory_errors = 0; 1209 catch_memory_errors = 0;
1215 } 1210 }
1216 1211
1217 static int xmon_depth_to_print = 64; 1212 static int xmon_depth_to_print = 64;
1218 1213
1219 #ifdef CONFIG_PPC64 1214 #ifdef CONFIG_PPC64
1220 #define LRSAVE_OFFSET 0x10 1215 #define LRSAVE_OFFSET 0x10
1221 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ 1216 #define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */
1222 #define MARKER_OFFSET 0x60 1217 #define MARKER_OFFSET 0x60
1223 #define REGS_OFFSET 0x70 1218 #define REGS_OFFSET 0x70
1224 #else 1219 #else
1225 #define LRSAVE_OFFSET 4 1220 #define LRSAVE_OFFSET 4
1226 #define REG_FRAME_MARKER 0x72656773 1221 #define REG_FRAME_MARKER 0x72656773
1227 #define MARKER_OFFSET 8 1222 #define MARKER_OFFSET 8
1228 #define REGS_OFFSET 16 1223 #define REGS_OFFSET 16
1229 #endif 1224 #endif
1230 1225
1231 static void xmon_show_stack(unsigned long sp, unsigned long lr, 1226 static void xmon_show_stack(unsigned long sp, unsigned long lr,
1232 unsigned long pc) 1227 unsigned long pc)
1233 { 1228 {
1234 unsigned long ip; 1229 unsigned long ip;
1235 unsigned long newsp; 1230 unsigned long newsp;
1236 unsigned long marker; 1231 unsigned long marker;
1237 int count = 0; 1232 int count = 0;
1238 struct pt_regs regs; 1233 struct pt_regs regs;
1239 1234
1240 do { 1235 do {
1241 if (sp < PAGE_OFFSET) { 1236 if (sp < PAGE_OFFSET) {
1242 if (sp != 0) 1237 if (sp != 0)
1243 printf("SP (%lx) is in userspace\n", sp); 1238 printf("SP (%lx) is in userspace\n", sp);
1244 break; 1239 break;
1245 } 1240 }
1246 1241
1247 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) 1242 if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long))
1248 || !mread(sp, &newsp, sizeof(unsigned long))) { 1243 || !mread(sp, &newsp, sizeof(unsigned long))) {
1249 printf("Couldn't read stack frame at %lx\n", sp); 1244 printf("Couldn't read stack frame at %lx\n", sp);
1250 break; 1245 break;
1251 } 1246 }
1252 1247
1253 /* 1248 /*
1254 * For the first stack frame, try to work out if 1249 * For the first stack frame, try to work out if
1255 * LR and/or the saved LR value in the bottommost 1250 * LR and/or the saved LR value in the bottommost
1256 * stack frame are valid. 1251 * stack frame are valid.
1257 */ 1252 */
1258 if ((pc | lr) != 0) { 1253 if ((pc | lr) != 0) {
1259 unsigned long fnstart, fnend; 1254 unsigned long fnstart, fnend;
1260 unsigned long nextip; 1255 unsigned long nextip;
1261 int printip = 1; 1256 int printip = 1;
1262 1257
1263 get_function_bounds(pc, &fnstart, &fnend); 1258 get_function_bounds(pc, &fnstart, &fnend);
1264 nextip = 0; 1259 nextip = 0;
1265 if (newsp > sp) 1260 if (newsp > sp)
1266 mread(newsp + LRSAVE_OFFSET, &nextip, 1261 mread(newsp + LRSAVE_OFFSET, &nextip,
1267 sizeof(unsigned long)); 1262 sizeof(unsigned long));
1268 if (lr == ip) { 1263 if (lr == ip) {
1269 if (lr < PAGE_OFFSET 1264 if (lr < PAGE_OFFSET
1270 || (fnstart <= lr && lr < fnend)) 1265 || (fnstart <= lr && lr < fnend))
1271 printip = 0; 1266 printip = 0;
1272 } else if (lr == nextip) { 1267 } else if (lr == nextip) {
1273 printip = 0; 1268 printip = 0;
1274 } else if (lr >= PAGE_OFFSET 1269 } else if (lr >= PAGE_OFFSET
1275 && !(fnstart <= lr && lr < fnend)) { 1270 && !(fnstart <= lr && lr < fnend)) {
1276 printf("[link register ] "); 1271 printf("[link register ] ");
1277 xmon_print_symbol(lr, " ", "\n"); 1272 xmon_print_symbol(lr, " ", "\n");
1278 } 1273 }
1279 if (printip) { 1274 if (printip) {
1280 printf("["REG"] ", sp); 1275 printf("["REG"] ", sp);
1281 xmon_print_symbol(ip, " ", " (unreliable)\n"); 1276 xmon_print_symbol(ip, " ", " (unreliable)\n");
1282 } 1277 }
1283 pc = lr = 0; 1278 pc = lr = 0;
1284 1279
1285 } else { 1280 } else {
1286 printf("["REG"] ", sp); 1281 printf("["REG"] ", sp);
1287 xmon_print_symbol(ip, " ", "\n"); 1282 xmon_print_symbol(ip, " ", "\n");
1288 } 1283 }
1289 1284
1290 /* Look for "regshere" marker to see if this is 1285 /* Look for "regshere" marker to see if this is
1291 an exception frame. */ 1286 an exception frame. */
1292 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) 1287 if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
1293 && marker == REG_FRAME_MARKER) { 1288 && marker == REG_FRAME_MARKER) {
1294 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs)) 1289 if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
1295 != sizeof(regs)) { 1290 != sizeof(regs)) {
1296 printf("Couldn't read registers at %lx\n", 1291 printf("Couldn't read registers at %lx\n",
1297 sp + REGS_OFFSET); 1292 sp + REGS_OFFSET);
1298 break; 1293 break;
1299 } 1294 }
1300 printf("--- Exception: %lx %s at ", regs.trap, 1295 printf("--- Exception: %lx %s at ", regs.trap,
1301 getvecname(TRAP(&regs))); 1296 getvecname(TRAP(&regs)));
1302 pc = regs.nip; 1297 pc = regs.nip;
1303 lr = regs.link; 1298 lr = regs.link;
1304 xmon_print_symbol(pc, " ", "\n"); 1299 xmon_print_symbol(pc, " ", "\n");
1305 } 1300 }
1306 1301
1307 if (newsp == 0) 1302 if (newsp == 0)
1308 break; 1303 break;
1309 1304
1310 sp = newsp; 1305 sp = newsp;
1311 } while (count++ < xmon_depth_to_print); 1306 } while (count++ < xmon_depth_to_print);
1312 } 1307 }
1313 1308
1314 static void backtrace(struct pt_regs *excp) 1309 static void backtrace(struct pt_regs *excp)
1315 { 1310 {
1316 unsigned long sp; 1311 unsigned long sp;
1317 1312
1318 if (scanhex(&sp)) 1313 if (scanhex(&sp))
1319 xmon_show_stack(sp, 0, 0); 1314 xmon_show_stack(sp, 0, 0);
1320 else 1315 else
1321 xmon_show_stack(excp->gpr[1], excp->link, excp->nip); 1316 xmon_show_stack(excp->gpr[1], excp->link, excp->nip);
1322 scannl(); 1317 scannl();
1323 } 1318 }
1324 1319
1325 static void print_bug_trap(struct pt_regs *regs) 1320 static void print_bug_trap(struct pt_regs *regs)
1326 { 1321 {
1327 struct bug_entry *bug; 1322 struct bug_entry *bug;
1328 unsigned long addr; 1323 unsigned long addr;
1329 1324
1330 if (regs->msr & MSR_PR) 1325 if (regs->msr & MSR_PR)
1331 return; /* not in kernel */ 1326 return; /* not in kernel */
1332 addr = regs->nip; /* address of trap instruction */ 1327 addr = regs->nip; /* address of trap instruction */
1333 if (addr < PAGE_OFFSET) 1328 if (addr < PAGE_OFFSET)
1334 return; 1329 return;
1335 bug = find_bug(regs->nip); 1330 bug = find_bug(regs->nip);
1336 if (bug == NULL) 1331 if (bug == NULL)
1337 return; 1332 return;
1338 if (bug->line & BUG_WARNING_TRAP) 1333 if (bug->line & BUG_WARNING_TRAP)
1339 return; 1334 return;
1340 1335
1341 printf("kernel BUG in %s at %s:%d!\n", 1336 printf("kernel BUG in %s at %s:%d!\n",
1342 bug->function, bug->file, (unsigned int)bug->line); 1337 bug->function, bug->file, (unsigned int)bug->line);
1343 } 1338 }
1344 1339
1345 void excprint(struct pt_regs *fp) 1340 void excprint(struct pt_regs *fp)
1346 { 1341 {
1347 unsigned long trap; 1342 unsigned long trap;
1348 1343
1349 #ifdef CONFIG_SMP 1344 #ifdef CONFIG_SMP
1350 printf("cpu 0x%x: ", smp_processor_id()); 1345 printf("cpu 0x%x: ", smp_processor_id());
1351 #endif /* CONFIG_SMP */ 1346 #endif /* CONFIG_SMP */
1352 1347
1353 trap = TRAP(fp); 1348 trap = TRAP(fp);
1354 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp); 1349 printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(trap), fp);
1355 printf(" pc: "); 1350 printf(" pc: ");
1356 xmon_print_symbol(fp->nip, ": ", "\n"); 1351 xmon_print_symbol(fp->nip, ": ", "\n");
1357 1352
1358 printf(" lr: ", fp->link); 1353 printf(" lr: ", fp->link);
1359 xmon_print_symbol(fp->link, ": ", "\n"); 1354 xmon_print_symbol(fp->link, ": ", "\n");
1360 1355
1361 printf(" sp: %lx\n", fp->gpr[1]); 1356 printf(" sp: %lx\n", fp->gpr[1]);
1362 printf(" msr: %lx\n", fp->msr); 1357 printf(" msr: %lx\n", fp->msr);
1363 1358
1364 if (trap == 0x300 || trap == 0x380 || trap == 0x600) { 1359 if (trap == 0x300 || trap == 0x380 || trap == 0x600) {
1365 printf(" dar: %lx\n", fp->dar); 1360 printf(" dar: %lx\n", fp->dar);
1366 if (trap != 0x380) 1361 if (trap != 0x380)
1367 printf(" dsisr: %lx\n", fp->dsisr); 1362 printf(" dsisr: %lx\n", fp->dsisr);
1368 } 1363 }
1369 1364
1370 printf(" current = 0x%lx\n", current); 1365 printf(" current = 0x%lx\n", current);
1371 #ifdef CONFIG_PPC64 1366 #ifdef CONFIG_PPC64
1372 printf(" paca = 0x%lx\n", get_paca()); 1367 printf(" paca = 0x%lx\n", get_paca());
1373 #endif 1368 #endif
1374 if (current) { 1369 if (current) {
1375 printf(" pid = %ld, comm = %s\n", 1370 printf(" pid = %ld, comm = %s\n",
1376 current->pid, current->comm); 1371 current->pid, current->comm);
1377 } 1372 }
1378 1373
1379 if (trap == 0x700) 1374 if (trap == 0x700)
1380 print_bug_trap(fp); 1375 print_bug_trap(fp);
1381 } 1376 }
1382 1377
1383 void prregs(struct pt_regs *fp) 1378 void prregs(struct pt_regs *fp)
1384 { 1379 {
1385 int n, trap; 1380 int n, trap;
1386 unsigned long base; 1381 unsigned long base;
1387 struct pt_regs regs; 1382 struct pt_regs regs;
1388 1383
1389 if (scanhex(&base)) { 1384 if (scanhex(&base)) {
1390 if (setjmp(bus_error_jmp) == 0) { 1385 if (setjmp(bus_error_jmp) == 0) {
1391 catch_memory_errors = 1; 1386 catch_memory_errors = 1;
1392 sync(); 1387 sync();
1393 regs = *(struct pt_regs *)base; 1388 regs = *(struct pt_regs *)base;
1394 sync(); 1389 sync();
1395 __delay(200); 1390 __delay(200);
1396 } else { 1391 } else {
1397 catch_memory_errors = 0; 1392 catch_memory_errors = 0;
1398 printf("*** Error reading registers from "REG"\n", 1393 printf("*** Error reading registers from "REG"\n",
1399 base); 1394 base);
1400 return; 1395 return;
1401 } 1396 }
1402 catch_memory_errors = 0; 1397 catch_memory_errors = 0;
1403 fp = &regs; 1398 fp = &regs;
1404 } 1399 }
1405 1400
1406 #ifdef CONFIG_PPC64 1401 #ifdef CONFIG_PPC64
1407 if (FULL_REGS(fp)) { 1402 if (FULL_REGS(fp)) {
1408 for (n = 0; n < 16; ++n) 1403 for (n = 0; n < 16; ++n)
1409 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1404 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1410 n, fp->gpr[n], n+16, fp->gpr[n+16]); 1405 n, fp->gpr[n], n+16, fp->gpr[n+16]);
1411 } else { 1406 } else {
1412 for (n = 0; n < 7; ++n) 1407 for (n = 0; n < 7; ++n)
1413 printf("R%.2ld = "REG" R%.2ld = "REG"\n", 1408 printf("R%.2ld = "REG" R%.2ld = "REG"\n",
1414 n, fp->gpr[n], n+7, fp->gpr[n+7]); 1409 n, fp->gpr[n], n+7, fp->gpr[n+7]);
1415 } 1410 }
1416 #else 1411 #else
1417 for (n = 0; n < 32; ++n) { 1412 for (n = 0; n < 32; ++n) {
1418 printf("R%.2d = %.8x%s", n, fp->gpr[n], 1413 printf("R%.2d = %.8x%s", n, fp->gpr[n],
1419 (n & 3) == 3? "\n": " "); 1414 (n & 3) == 3? "\n": " ");
1420 if (n == 12 && !FULL_REGS(fp)) { 1415 if (n == 12 && !FULL_REGS(fp)) {
1421 printf("\n"); 1416 printf("\n");
1422 break; 1417 break;
1423 } 1418 }
1424 } 1419 }
1425 #endif 1420 #endif
1426 printf("pc = "); 1421 printf("pc = ");
1427 xmon_print_symbol(fp->nip, " ", "\n"); 1422 xmon_print_symbol(fp->nip, " ", "\n");
1428 printf("lr = "); 1423 printf("lr = ");
1429 xmon_print_symbol(fp->link, " ", "\n"); 1424 xmon_print_symbol(fp->link, " ", "\n");
1430 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr); 1425 printf("msr = "REG" cr = %.8lx\n", fp->msr, fp->ccr);
1431 printf("ctr = "REG" xer = "REG" trap = %4lx\n", 1426 printf("ctr = "REG" xer = "REG" trap = %4lx\n",
1432 fp->ctr, fp->xer, fp->trap); 1427 fp->ctr, fp->xer, fp->trap);
1433 trap = TRAP(fp); 1428 trap = TRAP(fp);
1434 if (trap == 0x300 || trap == 0x380 || trap == 0x600) 1429 if (trap == 0x300 || trap == 0x380 || trap == 0x600)
1435 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr); 1430 printf("dar = "REG" dsisr = %.8lx\n", fp->dar, fp->dsisr);
1436 } 1431 }
1437 1432
1438 void cacheflush(void) 1433 void cacheflush(void)
1439 { 1434 {
1440 int cmd; 1435 int cmd;
1441 unsigned long nflush; 1436 unsigned long nflush;
1442 1437
1443 cmd = inchar(); 1438 cmd = inchar();
1444 if (cmd != 'i') 1439 if (cmd != 'i')
1445 termch = cmd; 1440 termch = cmd;
1446 scanhex((void *)&adrs); 1441 scanhex((void *)&adrs);
1447 if (termch != '\n') 1442 if (termch != '\n')
1448 termch = 0; 1443 termch = 0;
1449 nflush = 1; 1444 nflush = 1;
1450 scanhex(&nflush); 1445 scanhex(&nflush);
1451 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES; 1446 nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
1452 if (setjmp(bus_error_jmp) == 0) { 1447 if (setjmp(bus_error_jmp) == 0) {
1453 catch_memory_errors = 1; 1448 catch_memory_errors = 1;
1454 sync(); 1449 sync();
1455 1450
1456 if (cmd != 'i') { 1451 if (cmd != 'i') {
1457 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1452 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1458 cflush((void *) adrs); 1453 cflush((void *) adrs);
1459 } else { 1454 } else {
1460 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES) 1455 for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
1461 cinval((void *) adrs); 1456 cinval((void *) adrs);
1462 } 1457 }
1463 sync(); 1458 sync();
1464 /* wait a little while to see if we get a machine check */ 1459 /* wait a little while to see if we get a machine check */
1465 __delay(200); 1460 __delay(200);
1466 } 1461 }
1467 catch_memory_errors = 0; 1462 catch_memory_errors = 0;
1468 } 1463 }
1469 1464
1470 unsigned long 1465 unsigned long
1471 read_spr(int n) 1466 read_spr(int n)
1472 { 1467 {
1473 unsigned int instrs[2]; 1468 unsigned int instrs[2];
1474 unsigned long (*code)(void); 1469 unsigned long (*code)(void);
1475 unsigned long opd[3]; 1470 unsigned long opd[3];
1476 unsigned long ret = -1UL; 1471 unsigned long ret = -1UL;
1477 1472
1478 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1473 instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1479 instrs[1] = 0x4e800020; 1474 instrs[1] = 0x4e800020;
1480 opd[0] = (unsigned long)instrs; 1475 opd[0] = (unsigned long)instrs;
1481 opd[1] = 0; 1476 opd[1] = 0;
1482 opd[2] = 0; 1477 opd[2] = 0;
1483 store_inst(instrs); 1478 store_inst(instrs);
1484 store_inst(instrs+1); 1479 store_inst(instrs+1);
1485 code = (unsigned long (*)(void)) opd; 1480 code = (unsigned long (*)(void)) opd;
1486 1481
1487 if (setjmp(bus_error_jmp) == 0) { 1482 if (setjmp(bus_error_jmp) == 0) {
1488 catch_memory_errors = 1; 1483 catch_memory_errors = 1;
1489 sync(); 1484 sync();
1490 1485
1491 ret = code(); 1486 ret = code();
1492 1487
1493 sync(); 1488 sync();
1494 /* wait a little while to see if we get a machine check */ 1489 /* wait a little while to see if we get a machine check */
1495 __delay(200); 1490 __delay(200);
1496 n = size; 1491 n = size;
1497 } 1492 }
1498 1493
1499 return ret; 1494 return ret;
1500 } 1495 }
1501 1496
1502 void 1497 void
1503 write_spr(int n, unsigned long val) 1498 write_spr(int n, unsigned long val)
1504 { 1499 {
1505 unsigned int instrs[2]; 1500 unsigned int instrs[2];
1506 unsigned long (*code)(unsigned long); 1501 unsigned long (*code)(unsigned long);
1507 unsigned long opd[3]; 1502 unsigned long opd[3];
1508 1503
1509 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); 1504 instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
1510 instrs[1] = 0x4e800020; 1505 instrs[1] = 0x4e800020;
1511 opd[0] = (unsigned long)instrs; 1506 opd[0] = (unsigned long)instrs;
1512 opd[1] = 0; 1507 opd[1] = 0;
1513 opd[2] = 0; 1508 opd[2] = 0;
1514 store_inst(instrs); 1509 store_inst(instrs);
1515 store_inst(instrs+1); 1510 store_inst(instrs+1);
1516 code = (unsigned long (*)(unsigned long)) opd; 1511 code = (unsigned long (*)(unsigned long)) opd;
1517 1512
1518 if (setjmp(bus_error_jmp) == 0) { 1513 if (setjmp(bus_error_jmp) == 0) {
1519 catch_memory_errors = 1; 1514 catch_memory_errors = 1;
1520 sync(); 1515 sync();
1521 1516
1522 code(val); 1517 code(val);
1523 1518
1524 sync(); 1519 sync();
1525 /* wait a little while to see if we get a machine check */ 1520 /* wait a little while to see if we get a machine check */
1526 __delay(200); 1521 __delay(200);
1527 n = size; 1522 n = size;
1528 } 1523 }
1529 } 1524 }
1530 1525
1531 static unsigned long regno; 1526 static unsigned long regno;
1532 extern char exc_prolog; 1527 extern char exc_prolog;
1533 extern char dec_exc; 1528 extern char dec_exc;
1534 1529
1535 void super_regs(void) 1530 void super_regs(void)
1536 { 1531 {
1537 int cmd; 1532 int cmd;
1538 unsigned long val; 1533 unsigned long val;
1539 #ifdef CONFIG_PPC_ISERIES 1534 #ifdef CONFIG_PPC_ISERIES
1540 struct paca_struct *ptrPaca = NULL; 1535 struct paca_struct *ptrPaca = NULL;
1541 struct lppaca *ptrLpPaca = NULL; 1536 struct lppaca *ptrLpPaca = NULL;
1542 struct ItLpRegSave *ptrLpRegSave = NULL; 1537 struct ItLpRegSave *ptrLpRegSave = NULL;
1543 #endif 1538 #endif
1544 1539
1545 cmd = skipbl(); 1540 cmd = skipbl();
1546 if (cmd == '\n') { 1541 if (cmd == '\n') {
1547 unsigned long sp, toc; 1542 unsigned long sp, toc;
1548 asm("mr %0,1" : "=r" (sp) :); 1543 asm("mr %0,1" : "=r" (sp) :);
1549 asm("mr %0,2" : "=r" (toc) :); 1544 asm("mr %0,2" : "=r" (toc) :);
1550 1545
1551 printf("msr = "REG" sprg0= "REG"\n", 1546 printf("msr = "REG" sprg0= "REG"\n",
1552 mfmsr(), mfspr(SPRN_SPRG0)); 1547 mfmsr(), mfspr(SPRN_SPRG0));
1553 printf("pvr = "REG" sprg1= "REG"\n", 1548 printf("pvr = "REG" sprg1= "REG"\n",
1554 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1)); 1549 mfspr(SPRN_PVR), mfspr(SPRN_SPRG1));
1555 printf("dec = "REG" sprg2= "REG"\n", 1550 printf("dec = "REG" sprg2= "REG"\n",
1556 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2)); 1551 mfspr(SPRN_DEC), mfspr(SPRN_SPRG2));
1557 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1552 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1558 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1553 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1559 #ifdef CONFIG_PPC_ISERIES 1554 #ifdef CONFIG_PPC_ISERIES
1560 // Dump out relevant Paca data areas. 1555 // Dump out relevant Paca data areas.
1561 printf("Paca: \n"); 1556 printf("Paca: \n");
1562 ptrPaca = get_paca(); 1557 ptrPaca = get_paca();
1563 1558
1564 printf(" Local Processor Control Area (LpPaca): \n"); 1559 printf(" Local Processor Control Area (LpPaca): \n");
1565 ptrLpPaca = ptrPaca->lppaca_ptr; 1560 ptrLpPaca = ptrPaca->lppaca_ptr;
1566 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", 1561 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1567 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); 1562 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1568 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", 1563 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1569 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); 1564 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1570 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); 1565 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1571 1566
1572 printf(" Local Processor Register Save Area (LpRegSave): \n"); 1567 printf(" Local Processor Register Save Area (LpRegSave): \n");
1573 ptrLpRegSave = ptrPaca->reg_save_ptr; 1568 ptrLpRegSave = ptrPaca->reg_save_ptr;
1574 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", 1569 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1575 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); 1570 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1576 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", 1571 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1577 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); 1572 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1578 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", 1573 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1579 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); 1574 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1580 #endif 1575 #endif
1581 1576
1582 return; 1577 return;
1583 } 1578 }
1584 1579
1585 scanhex(&regno); 1580 scanhex(&regno);
1586 switch (cmd) { 1581 switch (cmd) {
1587 case 'w': 1582 case 'w':
1588 val = read_spr(regno); 1583 val = read_spr(regno);
1589 scanhex(&val); 1584 scanhex(&val);
1590 write_spr(regno, val); 1585 write_spr(regno, val);
1591 /* fall through */ 1586 /* fall through */
1592 case 'r': 1587 case 'r':
1593 printf("spr %lx = %lx\n", regno, read_spr(regno)); 1588 printf("spr %lx = %lx\n", regno, read_spr(regno));
1594 break; 1589 break;
1595 } 1590 }
1596 scannl(); 1591 scannl();
1597 } 1592 }
1598 1593
1599 /* 1594 /*
1600 * Stuff for reading and writing memory safely 1595 * Stuff for reading and writing memory safely
1601 */ 1596 */
1602 int 1597 int
1603 mread(unsigned long adrs, void *buf, int size) 1598 mread(unsigned long adrs, void *buf, int size)
1604 { 1599 {
1605 volatile int n; 1600 volatile int n;
1606 char *p, *q; 1601 char *p, *q;
1607 1602
1608 n = 0; 1603 n = 0;
1609 if (setjmp(bus_error_jmp) == 0) { 1604 if (setjmp(bus_error_jmp) == 0) {
1610 catch_memory_errors = 1; 1605 catch_memory_errors = 1;
1611 sync(); 1606 sync();
1612 p = (char *)adrs; 1607 p = (char *)adrs;
1613 q = (char *)buf; 1608 q = (char *)buf;
1614 switch (size) { 1609 switch (size) {
1615 case 2: 1610 case 2:
1616 *(u16 *)q = *(u16 *)p; 1611 *(u16 *)q = *(u16 *)p;
1617 break; 1612 break;
1618 case 4: 1613 case 4:
1619 *(u32 *)q = *(u32 *)p; 1614 *(u32 *)q = *(u32 *)p;
1620 break; 1615 break;
1621 case 8: 1616 case 8:
1622 *(u64 *)q = *(u64 *)p; 1617 *(u64 *)q = *(u64 *)p;
1623 break; 1618 break;
1624 default: 1619 default:
1625 for( ; n < size; ++n) { 1620 for( ; n < size; ++n) {
1626 *q++ = *p++; 1621 *q++ = *p++;
1627 sync(); 1622 sync();
1628 } 1623 }
1629 } 1624 }
1630 sync(); 1625 sync();
1631 /* wait a little while to see if we get a machine check */ 1626 /* wait a little while to see if we get a machine check */
1632 __delay(200); 1627 __delay(200);
1633 n = size; 1628 n = size;
1634 } 1629 }
1635 catch_memory_errors = 0; 1630 catch_memory_errors = 0;
1636 return n; 1631 return n;
1637 } 1632 }
1638 1633
1639 int 1634 int
1640 mwrite(unsigned long adrs, void *buf, int size) 1635 mwrite(unsigned long adrs, void *buf, int size)
1641 { 1636 {
1642 volatile int n; 1637 volatile int n;
1643 char *p, *q; 1638 char *p, *q;
1644 1639
1645 n = 0; 1640 n = 0;
1646 if (setjmp(bus_error_jmp) == 0) { 1641 if (setjmp(bus_error_jmp) == 0) {
1647 catch_memory_errors = 1; 1642 catch_memory_errors = 1;
1648 sync(); 1643 sync();
1649 p = (char *) adrs; 1644 p = (char *) adrs;
1650 q = (char *) buf; 1645 q = (char *) buf;
1651 switch (size) { 1646 switch (size) {
1652 case 2: 1647 case 2:
1653 *(u16 *)p = *(u16 *)q; 1648 *(u16 *)p = *(u16 *)q;
1654 break; 1649 break;
1655 case 4: 1650 case 4:
1656 *(u32 *)p = *(u32 *)q; 1651 *(u32 *)p = *(u32 *)q;
1657 break; 1652 break;
1658 case 8: 1653 case 8:
1659 *(u64 *)p = *(u64 *)q; 1654 *(u64 *)p = *(u64 *)q;
1660 break; 1655 break;
1661 default: 1656 default:
1662 for ( ; n < size; ++n) { 1657 for ( ; n < size; ++n) {
1663 *p++ = *q++; 1658 *p++ = *q++;
1664 sync(); 1659 sync();
1665 } 1660 }
1666 } 1661 }
1667 sync(); 1662 sync();
1668 /* wait a little while to see if we get a machine check */ 1663 /* wait a little while to see if we get a machine check */
1669 __delay(200); 1664 __delay(200);
1670 n = size; 1665 n = size;
1671 } else { 1666 } else {
1672 printf("*** Error writing address %x\n", adrs + n); 1667 printf("*** Error writing address %x\n", adrs + n);
1673 } 1668 }
1674 catch_memory_errors = 0; 1669 catch_memory_errors = 0;
1675 return n; 1670 return n;
1676 } 1671 }
1677 1672
1678 static int fault_type; 1673 static int fault_type;
1679 static int fault_except; 1674 static int fault_except;
1680 static char *fault_chars[] = { "--", "**", "##" }; 1675 static char *fault_chars[] = { "--", "**", "##" };
1681 1676
1682 static int handle_fault(struct pt_regs *regs) 1677 static int handle_fault(struct pt_regs *regs)
1683 { 1678 {
1684 fault_except = TRAP(regs); 1679 fault_except = TRAP(regs);
1685 switch (TRAP(regs)) { 1680 switch (TRAP(regs)) {
1686 case 0x200: 1681 case 0x200:
1687 fault_type = 0; 1682 fault_type = 0;
1688 break; 1683 break;
1689 case 0x300: 1684 case 0x300:
1690 case 0x380: 1685 case 0x380:
1691 fault_type = 1; 1686 fault_type = 1;
1692 break; 1687 break;
1693 default: 1688 default:
1694 fault_type = 2; 1689 fault_type = 2;
1695 } 1690 }
1696 1691
1697 longjmp(bus_error_jmp, 1); 1692 longjmp(bus_error_jmp, 1);
1698 1693
1699 return 0; 1694 return 0;
1700 } 1695 }
1701 1696
1702 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t)) 1697 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
1703 1698
1704 void 1699 void
1705 byterev(unsigned char *val, int size) 1700 byterev(unsigned char *val, int size)
1706 { 1701 {
1707 int t; 1702 int t;
1708 1703
1709 switch (size) { 1704 switch (size) {
1710 case 2: 1705 case 2:
1711 SWAP(val[0], val[1], t); 1706 SWAP(val[0], val[1], t);
1712 break; 1707 break;
1713 case 4: 1708 case 4:
1714 SWAP(val[0], val[3], t); 1709 SWAP(val[0], val[3], t);
1715 SWAP(val[1], val[2], t); 1710 SWAP(val[1], val[2], t);
1716 break; 1711 break;
1717 case 8: /* is there really any use for this? */ 1712 case 8: /* is there really any use for this? */
1718 SWAP(val[0], val[7], t); 1713 SWAP(val[0], val[7], t);
1719 SWAP(val[1], val[6], t); 1714 SWAP(val[1], val[6], t);
1720 SWAP(val[2], val[5], t); 1715 SWAP(val[2], val[5], t);
1721 SWAP(val[3], val[4], t); 1716 SWAP(val[3], val[4], t);
1722 break; 1717 break;
1723 } 1718 }
1724 } 1719 }
1725 1720
1726 static int brev; 1721 static int brev;
1727 static int mnoread; 1722 static int mnoread;
1728 1723
1729 static char *memex_help_string = 1724 static char *memex_help_string =
1730 "Memory examine command usage:\n" 1725 "Memory examine command usage:\n"
1731 "m [addr] [flags] examine/change memory\n" 1726 "m [addr] [flags] examine/change memory\n"
1732 " addr is optional. will start where left off.\n" 1727 " addr is optional. will start where left off.\n"
1733 " flags may include chars from this set:\n" 1728 " flags may include chars from this set:\n"
1734 " b modify by bytes (default)\n" 1729 " b modify by bytes (default)\n"
1735 " w modify by words (2 byte)\n" 1730 " w modify by words (2 byte)\n"
1736 " l modify by longs (4 byte)\n" 1731 " l modify by longs (4 byte)\n"
1737 " d modify by doubleword (8 byte)\n" 1732 " d modify by doubleword (8 byte)\n"
1738 " r toggle reverse byte order mode\n" 1733 " r toggle reverse byte order mode\n"
1739 " n do not read memory (for i/o spaces)\n" 1734 " n do not read memory (for i/o spaces)\n"
1740 " . ok to read (default)\n" 1735 " . ok to read (default)\n"
1741 "NOTE: flags are saved as defaults\n" 1736 "NOTE: flags are saved as defaults\n"
1742 ""; 1737 "";
1743 1738
1744 static char *memex_subcmd_help_string = 1739 static char *memex_subcmd_help_string =
1745 "Memory examine subcommands:\n" 1740 "Memory examine subcommands:\n"
1746 " hexval write this val to current location\n" 1741 " hexval write this val to current location\n"
1747 " 'string' write chars from string to this location\n" 1742 " 'string' write chars from string to this location\n"
1748 " ' increment address\n" 1743 " ' increment address\n"
1749 " ^ decrement address\n" 1744 " ^ decrement address\n"
1750 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" 1745 " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n"
1751 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" 1746 " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n"
1752 " ` clear no-read flag\n" 1747 " ` clear no-read flag\n"
1753 " ; stay at this addr\n" 1748 " ; stay at this addr\n"
1754 " v change to byte mode\n" 1749 " v change to byte mode\n"
1755 " w change to word (2 byte) mode\n" 1750 " w change to word (2 byte) mode\n"
1756 " l change to long (4 byte) mode\n" 1751 " l change to long (4 byte) mode\n"
1757 " u change to doubleword (8 byte) mode\n" 1752 " u change to doubleword (8 byte) mode\n"
1758 " m addr change current addr\n" 1753 " m addr change current addr\n"
1759 " n toggle no-read flag\n" 1754 " n toggle no-read flag\n"
1760 " r toggle byte reverse flag\n" 1755 " r toggle byte reverse flag\n"
1761 " < count back up count bytes\n" 1756 " < count back up count bytes\n"
1762 " > count skip forward count bytes\n" 1757 " > count skip forward count bytes\n"
1763 " x exit this mode\n" 1758 " x exit this mode\n"
1764 ""; 1759 "";
1765 1760
1766 void 1761 void
1767 memex(void) 1762 memex(void)
1768 { 1763 {
1769 int cmd, inc, i, nslash; 1764 int cmd, inc, i, nslash;
1770 unsigned long n; 1765 unsigned long n;
1771 unsigned char val[16]; 1766 unsigned char val[16];
1772 1767
1773 scanhex((void *)&adrs); 1768 scanhex((void *)&adrs);
1774 cmd = skipbl(); 1769 cmd = skipbl();
1775 if (cmd == '?') { 1770 if (cmd == '?') {
1776 printf(memex_help_string); 1771 printf(memex_help_string);
1777 return; 1772 return;
1778 } else { 1773 } else {
1779 termch = cmd; 1774 termch = cmd;
1780 } 1775 }
1781 last_cmd = "m\n"; 1776 last_cmd = "m\n";
1782 while ((cmd = skipbl()) != '\n') { 1777 while ((cmd = skipbl()) != '\n') {
1783 switch( cmd ){ 1778 switch( cmd ){
1784 case 'b': size = 1; break; 1779 case 'b': size = 1; break;
1785 case 'w': size = 2; break; 1780 case 'w': size = 2; break;
1786 case 'l': size = 4; break; 1781 case 'l': size = 4; break;
1787 case 'd': size = 8; break; 1782 case 'd': size = 8; break;
1788 case 'r': brev = !brev; break; 1783 case 'r': brev = !brev; break;
1789 case 'n': mnoread = 1; break; 1784 case 'n': mnoread = 1; break;
1790 case '.': mnoread = 0; break; 1785 case '.': mnoread = 0; break;
1791 } 1786 }
1792 } 1787 }
1793 if( size <= 0 ) 1788 if( size <= 0 )
1794 size = 1; 1789 size = 1;
1795 else if( size > 8 ) 1790 else if( size > 8 )
1796 size = 8; 1791 size = 8;
1797 for(;;){ 1792 for(;;){
1798 if (!mnoread) 1793 if (!mnoread)
1799 n = mread(adrs, val, size); 1794 n = mread(adrs, val, size);
1800 printf("%.16x%c", adrs, brev? 'r': ' '); 1795 printf("%.16x%c", adrs, brev? 'r': ' ');
1801 if (!mnoread) { 1796 if (!mnoread) {
1802 if (brev) 1797 if (brev)
1803 byterev(val, size); 1798 byterev(val, size);
1804 putchar(' '); 1799 putchar(' ');
1805 for (i = 0; i < n; ++i) 1800 for (i = 0; i < n; ++i)
1806 printf("%.2x", val[i]); 1801 printf("%.2x", val[i]);
1807 for (; i < size; ++i) 1802 for (; i < size; ++i)
1808 printf("%s", fault_chars[fault_type]); 1803 printf("%s", fault_chars[fault_type]);
1809 } 1804 }
1810 putchar(' '); 1805 putchar(' ');
1811 inc = size; 1806 inc = size;
1812 nslash = 0; 1807 nslash = 0;
1813 for(;;){ 1808 for(;;){
1814 if( scanhex(&n) ){ 1809 if( scanhex(&n) ){
1815 for (i = 0; i < size; ++i) 1810 for (i = 0; i < size; ++i)
1816 val[i] = n >> (i * 8); 1811 val[i] = n >> (i * 8);
1817 if (!brev) 1812 if (!brev)
1818 byterev(val, size); 1813 byterev(val, size);
1819 mwrite(adrs, val, size); 1814 mwrite(adrs, val, size);
1820 inc = size; 1815 inc = size;
1821 } 1816 }
1822 cmd = skipbl(); 1817 cmd = skipbl();
1823 if (cmd == '\n') 1818 if (cmd == '\n')
1824 break; 1819 break;
1825 inc = 0; 1820 inc = 0;
1826 switch (cmd) { 1821 switch (cmd) {
1827 case '\'': 1822 case '\'':
1828 for(;;){ 1823 for(;;){
1829 n = inchar(); 1824 n = inchar();
1830 if( n == '\\' ) 1825 if( n == '\\' )
1831 n = bsesc(); 1826 n = bsesc();
1832 else if( n == '\'' ) 1827 else if( n == '\'' )
1833 break; 1828 break;
1834 for (i = 0; i < size; ++i) 1829 for (i = 0; i < size; ++i)
1835 val[i] = n >> (i * 8); 1830 val[i] = n >> (i * 8);
1836 if (!brev) 1831 if (!brev)
1837 byterev(val, size); 1832 byterev(val, size);
1838 mwrite(adrs, val, size); 1833 mwrite(adrs, val, size);
1839 adrs += size; 1834 adrs += size;
1840 } 1835 }
1841 adrs -= size; 1836 adrs -= size;
1842 inc = size; 1837 inc = size;
1843 break; 1838 break;
1844 case ',': 1839 case ',':
1845 adrs += size; 1840 adrs += size;
1846 break; 1841 break;
1847 case '.': 1842 case '.':
1848 mnoread = 0; 1843 mnoread = 0;
1849 break; 1844 break;
1850 case ';': 1845 case ';':
1851 break; 1846 break;
1852 case 'x': 1847 case 'x':
1853 case EOF: 1848 case EOF:
1854 scannl(); 1849 scannl();
1855 return; 1850 return;
1856 case 'b': 1851 case 'b':
1857 case 'v': 1852 case 'v':
1858 size = 1; 1853 size = 1;
1859 break; 1854 break;
1860 case 'w': 1855 case 'w':
1861 size = 2; 1856 size = 2;
1862 break; 1857 break;
1863 case 'l': 1858 case 'l':
1864 size = 4; 1859 size = 4;
1865 break; 1860 break;
1866 case 'u': 1861 case 'u':
1867 size = 8; 1862 size = 8;
1868 break; 1863 break;
1869 case '^': 1864 case '^':
1870 adrs -= size; 1865 adrs -= size;
1871 break; 1866 break;
1872 break; 1867 break;
1873 case '/': 1868 case '/':
1874 if (nslash > 0) 1869 if (nslash > 0)
1875 adrs -= 1 << nslash; 1870 adrs -= 1 << nslash;
1876 else 1871 else
1877 nslash = 0; 1872 nslash = 0;
1878 nslash += 4; 1873 nslash += 4;
1879 adrs += 1 << nslash; 1874 adrs += 1 << nslash;
1880 break; 1875 break;
1881 case '\\': 1876 case '\\':
1882 if (nslash < 0) 1877 if (nslash < 0)
1883 adrs += 1 << -nslash; 1878 adrs += 1 << -nslash;
1884 else 1879 else
1885 nslash = 0; 1880 nslash = 0;
1886 nslash -= 4; 1881 nslash -= 4;
1887 adrs -= 1 << -nslash; 1882 adrs -= 1 << -nslash;
1888 break; 1883 break;
1889 case 'm': 1884 case 'm':
1890 scanhex((void *)&adrs); 1885 scanhex((void *)&adrs);
1891 break; 1886 break;
1892 case 'n': 1887 case 'n':
1893 mnoread = 1; 1888 mnoread = 1;
1894 break; 1889 break;
1895 case 'r': 1890 case 'r':
1896 brev = !brev; 1891 brev = !brev;
1897 break; 1892 break;
1898 case '<': 1893 case '<':
1899 n = size; 1894 n = size;
1900 scanhex(&n); 1895 scanhex(&n);
1901 adrs -= n; 1896 adrs -= n;
1902 break; 1897 break;
1903 case '>': 1898 case '>':
1904 n = size; 1899 n = size;
1905 scanhex(&n); 1900 scanhex(&n);
1906 adrs += n; 1901 adrs += n;
1907 break; 1902 break;
1908 case '?': 1903 case '?':
1909 printf(memex_subcmd_help_string); 1904 printf(memex_subcmd_help_string);
1910 break; 1905 break;
1911 } 1906 }
1912 } 1907 }
1913 adrs += inc; 1908 adrs += inc;
1914 } 1909 }
1915 } 1910 }
1916 1911
1917 int 1912 int
1918 bsesc(void) 1913 bsesc(void)
1919 { 1914 {
1920 int c; 1915 int c;
1921 1916
1922 c = inchar(); 1917 c = inchar();
1923 switch( c ){ 1918 switch( c ){
1924 case 'n': c = '\n'; break; 1919 case 'n': c = '\n'; break;
1925 case 'r': c = '\r'; break; 1920 case 'r': c = '\r'; break;
1926 case 'b': c = '\b'; break; 1921 case 'b': c = '\b'; break;
1927 case 't': c = '\t'; break; 1922 case 't': c = '\t'; break;
1928 } 1923 }
1929 return c; 1924 return c;
1930 } 1925 }
1931 1926
1932 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 1927 #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
1933 || ('a' <= (c) && (c) <= 'f') \ 1928 || ('a' <= (c) && (c) <= 'f') \
1934 || ('A' <= (c) && (c) <= 'F')) 1929 || ('A' <= (c) && (c) <= 'F'))
1935 void 1930 void
1936 dump(void) 1931 dump(void)
1937 { 1932 {
1938 int c; 1933 int c;
1939 1934
1940 c = inchar(); 1935 c = inchar();
1941 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 1936 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
1942 termch = c; 1937 termch = c;
1943 scanhex((void *)&adrs); 1938 scanhex((void *)&adrs);
1944 if (termch != '\n') 1939 if (termch != '\n')
1945 termch = 0; 1940 termch = 0;
1946 if (c == 'i') { 1941 if (c == 'i') {
1947 scanhex(&nidump); 1942 scanhex(&nidump);
1948 if (nidump == 0) 1943 if (nidump == 0)
1949 nidump = 16; 1944 nidump = 16;
1950 else if (nidump > MAX_DUMP) 1945 else if (nidump > MAX_DUMP)
1951 nidump = MAX_DUMP; 1946 nidump = MAX_DUMP;
1952 adrs += ppc_inst_dump(adrs, nidump, 1); 1947 adrs += ppc_inst_dump(adrs, nidump, 1);
1953 last_cmd = "di\n"; 1948 last_cmd = "di\n";
1954 } else { 1949 } else {
1955 scanhex(&ndump); 1950 scanhex(&ndump);
1956 if (ndump == 0) 1951 if (ndump == 0)
1957 ndump = 64; 1952 ndump = 64;
1958 else if (ndump > MAX_DUMP) 1953 else if (ndump > MAX_DUMP)
1959 ndump = MAX_DUMP; 1954 ndump = MAX_DUMP;
1960 prdump(adrs, ndump); 1955 prdump(adrs, ndump);
1961 adrs += ndump; 1956 adrs += ndump;
1962 last_cmd = "d\n"; 1957 last_cmd = "d\n";
1963 } 1958 }
1964 } 1959 }
1965 1960
1966 void 1961 void
1967 prdump(unsigned long adrs, long ndump) 1962 prdump(unsigned long adrs, long ndump)
1968 { 1963 {
1969 long n, m, c, r, nr; 1964 long n, m, c, r, nr;
1970 unsigned char temp[16]; 1965 unsigned char temp[16];
1971 1966
1972 for (n = ndump; n > 0;) { 1967 for (n = ndump; n > 0;) {
1973 printf(REG, adrs); 1968 printf(REG, adrs);
1974 putchar(' '); 1969 putchar(' ');
1975 r = n < 16? n: 16; 1970 r = n < 16? n: 16;
1976 nr = mread(adrs, temp, r); 1971 nr = mread(adrs, temp, r);
1977 adrs += nr; 1972 adrs += nr;
1978 for (m = 0; m < r; ++m) { 1973 for (m = 0; m < r; ++m) {
1979 if ((m & 7) == 0 && m > 0) 1974 if ((m & 7) == 0 && m > 0)
1980 putchar(' '); 1975 putchar(' ');
1981 if (m < nr) 1976 if (m < nr)
1982 printf("%.2x", temp[m]); 1977 printf("%.2x", temp[m]);
1983 else 1978 else
1984 printf("%s", fault_chars[fault_type]); 1979 printf("%s", fault_chars[fault_type]);
1985 } 1980 }
1986 if (m <= 8) 1981 if (m <= 8)
1987 printf(" "); 1982 printf(" ");
1988 for (; m < 16; ++m) 1983 for (; m < 16; ++m)
1989 printf(" "); 1984 printf(" ");
1990 printf(" |"); 1985 printf(" |");
1991 for (m = 0; m < r; ++m) { 1986 for (m = 0; m < r; ++m) {
1992 if (m < nr) { 1987 if (m < nr) {
1993 c = temp[m]; 1988 c = temp[m];
1994 putchar(' ' <= c && c <= '~'? c: '.'); 1989 putchar(' ' <= c && c <= '~'? c: '.');
1995 } else 1990 } else
1996 putchar(' '); 1991 putchar(' ');
1997 } 1992 }
1998 n -= r; 1993 n -= r;
1999 for (; m < 16; ++m) 1994 for (; m < 16; ++m)
2000 putchar(' '); 1995 putchar(' ');
2001 printf("|\n"); 1996 printf("|\n");
2002 if (nr < r) 1997 if (nr < r)
2003 break; 1998 break;
2004 } 1999 }
2005 } 2000 }
2006 2001
2007 int 2002 int
2008 ppc_inst_dump(unsigned long adr, long count, int praddr) 2003 ppc_inst_dump(unsigned long adr, long count, int praddr)
2009 { 2004 {
2010 int nr, dotted; 2005 int nr, dotted;
2011 unsigned long first_adr; 2006 unsigned long first_adr;
2012 unsigned long inst, last_inst = 0; 2007 unsigned long inst, last_inst = 0;
2013 unsigned char val[4]; 2008 unsigned char val[4];
2014 2009
2015 dotted = 0; 2010 dotted = 0;
2016 for (first_adr = adr; count > 0; --count, adr += 4) { 2011 for (first_adr = adr; count > 0; --count, adr += 4) {
2017 nr = mread(adr, val, 4); 2012 nr = mread(adr, val, 4);
2018 if (nr == 0) { 2013 if (nr == 0) {
2019 if (praddr) { 2014 if (praddr) {
2020 const char *x = fault_chars[fault_type]; 2015 const char *x = fault_chars[fault_type];
2021 printf(REG" %s%s%s%s\n", adr, x, x, x, x); 2016 printf(REG" %s%s%s%s\n", adr, x, x, x, x);
2022 } 2017 }
2023 break; 2018 break;
2024 } 2019 }
2025 inst = GETWORD(val); 2020 inst = GETWORD(val);
2026 if (adr > first_adr && inst == last_inst) { 2021 if (adr > first_adr && inst == last_inst) {
2027 if (!dotted) { 2022 if (!dotted) {
2028 printf(" ...\n"); 2023 printf(" ...\n");
2029 dotted = 1; 2024 dotted = 1;
2030 } 2025 }
2031 continue; 2026 continue;
2032 } 2027 }
2033 dotted = 0; 2028 dotted = 0;
2034 last_inst = inst; 2029 last_inst = inst;
2035 if (praddr) 2030 if (praddr)
2036 printf(REG" %.8x", adr, inst); 2031 printf(REG" %.8x", adr, inst);
2037 printf("\t"); 2032 printf("\t");
2038 print_insn_powerpc(inst, adr, 0); /* always returns 4 */ 2033 print_insn_powerpc(inst, adr, 0); /* always returns 4 */
2039 printf("\n"); 2034 printf("\n");
2040 } 2035 }
2041 return adr - first_adr; 2036 return adr - first_adr;
2042 } 2037 }
2043 2038
2044 void 2039 void
2045 print_address(unsigned long addr) 2040 print_address(unsigned long addr)
2046 { 2041 {
2047 xmon_print_symbol(addr, "\t# ", ""); 2042 xmon_print_symbol(addr, "\t# ", "");
2048 } 2043 }
2049 2044
2050 2045
2051 /* 2046 /*
2052 * Memory operations - move, set, print differences 2047 * Memory operations - move, set, print differences
2053 */ 2048 */
2054 static unsigned long mdest; /* destination address */ 2049 static unsigned long mdest; /* destination address */
2055 static unsigned long msrc; /* source address */ 2050 static unsigned long msrc; /* source address */
2056 static unsigned long mval; /* byte value to set memory to */ 2051 static unsigned long mval; /* byte value to set memory to */
2057 static unsigned long mcount; /* # bytes to affect */ 2052 static unsigned long mcount; /* # bytes to affect */
2058 static unsigned long mdiffs; /* max # differences to print */ 2053 static unsigned long mdiffs; /* max # differences to print */
2059 2054
2060 void 2055 void
2061 memops(int cmd) 2056 memops(int cmd)
2062 { 2057 {
2063 scanhex((void *)&mdest); 2058 scanhex((void *)&mdest);
2064 if( termch != '\n' ) 2059 if( termch != '\n' )
2065 termch = 0; 2060 termch = 0;
2066 scanhex((void *)(cmd == 's'? &mval: &msrc)); 2061 scanhex((void *)(cmd == 's'? &mval: &msrc));
2067 if( termch != '\n' ) 2062 if( termch != '\n' )
2068 termch = 0; 2063 termch = 0;
2069 scanhex((void *)&mcount); 2064 scanhex((void *)&mcount);
2070 switch( cmd ){ 2065 switch( cmd ){
2071 case 'm': 2066 case 'm':
2072 memmove((void *)mdest, (void *)msrc, mcount); 2067 memmove((void *)mdest, (void *)msrc, mcount);
2073 break; 2068 break;
2074 case 's': 2069 case 's':
2075 memset((void *)mdest, mval, mcount); 2070 memset((void *)mdest, mval, mcount);
2076 break; 2071 break;
2077 case 'd': 2072 case 'd':
2078 if( termch != '\n' ) 2073 if( termch != '\n' )
2079 termch = 0; 2074 termch = 0;
2080 scanhex((void *)&mdiffs); 2075 scanhex((void *)&mdiffs);
2081 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs); 2076 memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
2082 break; 2077 break;
2083 } 2078 }
2084 } 2079 }
2085 2080
2086 void 2081 void
2087 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr) 2082 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
2088 { 2083 {
2089 unsigned n, prt; 2084 unsigned n, prt;
2090 2085
2091 prt = 0; 2086 prt = 0;
2092 for( n = nb; n > 0; --n ) 2087 for( n = nb; n > 0; --n )
2093 if( *p1++ != *p2++ ) 2088 if( *p1++ != *p2++ )
2094 if( ++prt <= maxpr ) 2089 if( ++prt <= maxpr )
2095 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1, 2090 printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,
2096 p1[-1], p2 - 1, p2[-1]); 2091 p1[-1], p2 - 1, p2[-1]);
2097 if( prt > maxpr ) 2092 if( prt > maxpr )
2098 printf("Total of %d differences\n", prt); 2093 printf("Total of %d differences\n", prt);
2099 } 2094 }
2100 2095
2101 static unsigned mend; 2096 static unsigned mend;
2102 static unsigned mask; 2097 static unsigned mask;
2103 2098
2104 void 2099 void
2105 memlocate(void) 2100 memlocate(void)
2106 { 2101 {
2107 unsigned a, n; 2102 unsigned a, n;
2108 unsigned char val[4]; 2103 unsigned char val[4];
2109 2104
2110 last_cmd = "ml"; 2105 last_cmd = "ml";
2111 scanhex((void *)&mdest); 2106 scanhex((void *)&mdest);
2112 if (termch != '\n') { 2107 if (termch != '\n') {
2113 termch = 0; 2108 termch = 0;
2114 scanhex((void *)&mend); 2109 scanhex((void *)&mend);
2115 if (termch != '\n') { 2110 if (termch != '\n') {
2116 termch = 0; 2111 termch = 0;
2117 scanhex((void *)&mval); 2112 scanhex((void *)&mval);
2118 mask = ~0; 2113 mask = ~0;
2119 if (termch != '\n') termch = 0; 2114 if (termch != '\n') termch = 0;
2120 scanhex((void *)&mask); 2115 scanhex((void *)&mask);
2121 } 2116 }
2122 } 2117 }
2123 n = 0; 2118 n = 0;
2124 for (a = mdest; a < mend; a += 4) { 2119 for (a = mdest; a < mend; a += 4) {
2125 if (mread(a, val, 4) == 4 2120 if (mread(a, val, 4) == 4
2126 && ((GETWORD(val) ^ mval) & mask) == 0) { 2121 && ((GETWORD(val) ^ mval) & mask) == 0) {
2127 printf("%.16x: %.16x\n", a, GETWORD(val)); 2122 printf("%.16x: %.16x\n", a, GETWORD(val));
2128 if (++n >= 10) 2123 if (++n >= 10)
2129 break; 2124 break;
2130 } 2125 }
2131 } 2126 }
2132 } 2127 }
2133 2128
2134 static unsigned long mskip = 0x1000; 2129 static unsigned long mskip = 0x1000;
2135 static unsigned long mlim = 0xffffffff; 2130 static unsigned long mlim = 0xffffffff;
2136 2131
2137 void 2132 void
2138 memzcan(void) 2133 memzcan(void)
2139 { 2134 {
2140 unsigned char v; 2135 unsigned char v;
2141 unsigned a; 2136 unsigned a;
2142 int ok, ook; 2137 int ok, ook;
2143 2138
2144 scanhex(&mdest); 2139 scanhex(&mdest);
2145 if (termch != '\n') termch = 0; 2140 if (termch != '\n') termch = 0;
2146 scanhex(&mskip); 2141 scanhex(&mskip);
2147 if (termch != '\n') termch = 0; 2142 if (termch != '\n') termch = 0;
2148 scanhex(&mlim); 2143 scanhex(&mlim);
2149 ook = 0; 2144 ook = 0;
2150 for (a = mdest; a < mlim; a += mskip) { 2145 for (a = mdest; a < mlim; a += mskip) {
2151 ok = mread(a, &v, 1); 2146 ok = mread(a, &v, 1);
2152 if (ok && !ook) { 2147 if (ok && !ook) {
2153 printf("%.8x .. ", a); 2148 printf("%.8x .. ", a);
2154 fflush(stdout);
2155 } else if (!ok && ook) 2149 } else if (!ok && ook)
2156 printf("%.8x\n", a - mskip); 2150 printf("%.8x\n", a - mskip);
2157 ook = ok; 2151 ook = ok;
2158 if (a + mskip < a) 2152 if (a + mskip < a)
2159 break; 2153 break;
2160 } 2154 }
2161 if (ook) 2155 if (ook)
2162 printf("%.8x\n", a - mskip); 2156 printf("%.8x\n", a - mskip);
2163 } 2157 }
2164 2158
2165 void proccall(void) 2159 void proccall(void)
2166 { 2160 {
2167 unsigned long args[8]; 2161 unsigned long args[8];
2168 unsigned long ret; 2162 unsigned long ret;
2169 int i; 2163 int i;
2170 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long, 2164 typedef unsigned long (*callfunc_t)(unsigned long, unsigned long,
2171 unsigned long, unsigned long, unsigned long, 2165 unsigned long, unsigned long, unsigned long,
2172 unsigned long, unsigned long, unsigned long); 2166 unsigned long, unsigned long, unsigned long);
2173 callfunc_t func; 2167 callfunc_t func;
2174 2168
2175 if (!scanhex(&adrs)) 2169 if (!scanhex(&adrs))
2176 return; 2170 return;
2177 if (termch != '\n') 2171 if (termch != '\n')
2178 termch = 0; 2172 termch = 0;
2179 for (i = 0; i < 8; ++i) 2173 for (i = 0; i < 8; ++i)
2180 args[i] = 0; 2174 args[i] = 0;
2181 for (i = 0; i < 8; ++i) { 2175 for (i = 0; i < 8; ++i) {
2182 if (!scanhex(&args[i]) || termch == '\n') 2176 if (!scanhex(&args[i]) || termch == '\n')
2183 break; 2177 break;
2184 termch = 0; 2178 termch = 0;
2185 } 2179 }
2186 func = (callfunc_t) adrs; 2180 func = (callfunc_t) adrs;
2187 ret = 0; 2181 ret = 0;
2188 if (setjmp(bus_error_jmp) == 0) { 2182 if (setjmp(bus_error_jmp) == 0) {
2189 catch_memory_errors = 1; 2183 catch_memory_errors = 1;
2190 sync(); 2184 sync();
2191 ret = func(args[0], args[1], args[2], args[3], 2185 ret = func(args[0], args[1], args[2], args[3],
2192 args[4], args[5], args[6], args[7]); 2186 args[4], args[5], args[6], args[7]);
2193 sync(); 2187 sync();
2194 printf("return value is %x\n", ret); 2188 printf("return value is %x\n", ret);
2195 } else { 2189 } else {
2196 printf("*** %x exception occurred\n", fault_except); 2190 printf("*** %x exception occurred\n", fault_except);
2197 } 2191 }
2198 catch_memory_errors = 0; 2192 catch_memory_errors = 0;
2199 } 2193 }
2200 2194
2201 /* Input scanning routines */ 2195 /* Input scanning routines */
2202 int 2196 int
2203 skipbl(void) 2197 skipbl(void)
2204 { 2198 {
2205 int c; 2199 int c;
2206 2200
2207 if( termch != 0 ){ 2201 if( termch != 0 ){
2208 c = termch; 2202 c = termch;
2209 termch = 0; 2203 termch = 0;
2210 } else 2204 } else
2211 c = inchar(); 2205 c = inchar();
2212 while( c == ' ' || c == '\t' ) 2206 while( c == ' ' || c == '\t' )
2213 c = inchar(); 2207 c = inchar();
2214 return c; 2208 return c;
2215 } 2209 }
2216 2210
2217 #define N_PTREGS 44 2211 #define N_PTREGS 44
2218 static char *regnames[N_PTREGS] = { 2212 static char *regnames[N_PTREGS] = {
2219 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 2213 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
2220 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 2214 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
2221 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 2215 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
2222 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 2216 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
2223 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", 2217 "pc", "msr", "or3", "ctr", "lr", "xer", "ccr",
2224 #ifdef CONFIG_PPC64 2218 #ifdef CONFIG_PPC64
2225 "softe", 2219 "softe",
2226 #else 2220 #else
2227 "mq", 2221 "mq",
2228 #endif 2222 #endif
2229 "trap", "dar", "dsisr", "res" 2223 "trap", "dar", "dsisr", "res"
2230 }; 2224 };
2231 2225
2232 int 2226 int
2233 scanhex(unsigned long *vp) 2227 scanhex(unsigned long *vp)
2234 { 2228 {
2235 int c, d; 2229 int c, d;
2236 unsigned long v; 2230 unsigned long v;
2237 2231
2238 c = skipbl(); 2232 c = skipbl();
2239 if (c == '%') { 2233 if (c == '%') {
2240 /* parse register name */ 2234 /* parse register name */
2241 char regname[8]; 2235 char regname[8];
2242 int i; 2236 int i;
2243 2237
2244 for (i = 0; i < sizeof(regname) - 1; ++i) { 2238 for (i = 0; i < sizeof(regname) - 1; ++i) {
2245 c = inchar(); 2239 c = inchar();
2246 if (!isalnum(c)) { 2240 if (!isalnum(c)) {
2247 termch = c; 2241 termch = c;
2248 break; 2242 break;
2249 } 2243 }
2250 regname[i] = c; 2244 regname[i] = c;
2251 } 2245 }
2252 regname[i] = 0; 2246 regname[i] = 0;
2253 for (i = 0; i < N_PTREGS; ++i) { 2247 for (i = 0; i < N_PTREGS; ++i) {
2254 if (strcmp(regnames[i], regname) == 0) { 2248 if (strcmp(regnames[i], regname) == 0) {
2255 if (xmon_regs == NULL) { 2249 if (xmon_regs == NULL) {
2256 printf("regs not available\n"); 2250 printf("regs not available\n");
2257 return 0; 2251 return 0;
2258 } 2252 }
2259 *vp = ((unsigned long *)xmon_regs)[i]; 2253 *vp = ((unsigned long *)xmon_regs)[i];
2260 return 1; 2254 return 1;
2261 } 2255 }
2262 } 2256 }
2263 printf("invalid register name '%%%s'\n", regname); 2257 printf("invalid register name '%%%s'\n", regname);
2264 return 0; 2258 return 0;
2265 } 2259 }
2266 2260
2267 /* skip leading "0x" if any */ 2261 /* skip leading "0x" if any */
2268 2262
2269 if (c == '0') { 2263 if (c == '0') {
2270 c = inchar(); 2264 c = inchar();
2271 if (c == 'x') { 2265 if (c == 'x') {
2272 c = inchar(); 2266 c = inchar();
2273 } else { 2267 } else {
2274 d = hexdigit(c); 2268 d = hexdigit(c);
2275 if (d == EOF) { 2269 if (d == EOF) {
2276 termch = c; 2270 termch = c;
2277 *vp = 0; 2271 *vp = 0;
2278 return 1; 2272 return 1;
2279 } 2273 }
2280 } 2274 }
2281 } else if (c == '$') { 2275 } else if (c == '$') {
2282 int i; 2276 int i;
2283 for (i=0; i<63; i++) { 2277 for (i=0; i<63; i++) {
2284 c = inchar(); 2278 c = inchar();
2285 if (isspace(c)) { 2279 if (isspace(c)) {
2286 termch = c; 2280 termch = c;
2287 break; 2281 break;
2288 } 2282 }
2289 tmpstr[i] = c; 2283 tmpstr[i] = c;
2290 } 2284 }
2291 tmpstr[i++] = 0; 2285 tmpstr[i++] = 0;
2292 *vp = 0; 2286 *vp = 0;
2293 if (setjmp(bus_error_jmp) == 0) { 2287 if (setjmp(bus_error_jmp) == 0) {
2294 catch_memory_errors = 1; 2288 catch_memory_errors = 1;
2295 sync(); 2289 sync();
2296 *vp = kallsyms_lookup_name(tmpstr); 2290 *vp = kallsyms_lookup_name(tmpstr);
2297 sync(); 2291 sync();
2298 } 2292 }
2299 catch_memory_errors = 0; 2293 catch_memory_errors = 0;
2300 if (!(*vp)) { 2294 if (!(*vp)) {
2301 printf("unknown symbol '%s'\n", tmpstr); 2295 printf("unknown symbol '%s'\n", tmpstr);
2302 return 0; 2296 return 0;
2303 } 2297 }
2304 return 1; 2298 return 1;
2305 } 2299 }
2306 2300
2307 d = hexdigit(c); 2301 d = hexdigit(c);
2308 if (d == EOF) { 2302 if (d == EOF) {
2309 termch = c; 2303 termch = c;
2310 return 0; 2304 return 0;
2311 } 2305 }
2312 v = 0; 2306 v = 0;
2313 do { 2307 do {
2314 v = (v << 4) + d; 2308 v = (v << 4) + d;
2315 c = inchar(); 2309 c = inchar();
2316 d = hexdigit(c); 2310 d = hexdigit(c);
2317 } while (d != EOF); 2311 } while (d != EOF);
2318 termch = c; 2312 termch = c;
2319 *vp = v; 2313 *vp = v;
2320 return 1; 2314 return 1;
2321 } 2315 }
2322 2316
2323 void 2317 void
2324 scannl(void) 2318 scannl(void)
2325 { 2319 {
2326 int c; 2320 int c;
2327 2321
2328 c = termch; 2322 c = termch;
2329 termch = 0; 2323 termch = 0;
2330 while( c != '\n' ) 2324 while( c != '\n' )
2331 c = inchar(); 2325 c = inchar();
2332 } 2326 }
2333 2327
2334 int hexdigit(int c) 2328 int hexdigit(int c)
2335 { 2329 {
2336 if( '0' <= c && c <= '9' ) 2330 if( '0' <= c && c <= '9' )
2337 return c - '0'; 2331 return c - '0';
2338 if( 'A' <= c && c <= 'F' ) 2332 if( 'A' <= c && c <= 'F' )
2339 return c - ('A' - 10); 2333 return c - ('A' - 10);
2340 if( 'a' <= c && c <= 'f' ) 2334 if( 'a' <= c && c <= 'f' )
2341 return c - ('a' - 10); 2335 return c - ('a' - 10);
2342 return EOF; 2336 return EOF;
2343 } 2337 }
2344 2338
2345 void 2339 void
2346 getstring(char *s, int size) 2340 getstring(char *s, int size)
2347 { 2341 {
2348 int c; 2342 int c;
2349 2343
2350 c = skipbl(); 2344 c = skipbl();
2351 do { 2345 do {
2352 if( size > 1 ){ 2346 if( size > 1 ){
2353 *s++ = c; 2347 *s++ = c;
2354 --size; 2348 --size;
2355 } 2349 }
2356 c = inchar(); 2350 c = inchar();
2357 } while( c != ' ' && c != '\t' && c != '\n' ); 2351 } while( c != ' ' && c != '\t' && c != '\n' );
2358 termch = c; 2352 termch = c;
2359 *s = 0; 2353 *s = 0;
2360 } 2354 }
2361 2355
2362 static char line[256]; 2356 static char line[256];
2363 static char *lineptr; 2357 static char *lineptr;
2364 2358
2365 void 2359 void
2366 flush_input(void) 2360 flush_input(void)
2367 { 2361 {
2368 lineptr = NULL; 2362 lineptr = NULL;
2369 } 2363 }
2370 2364
2371 int 2365 int
2372 inchar(void) 2366 inchar(void)
2373 { 2367 {
2374 if (lineptr == NULL || *lineptr == 0) { 2368 if (lineptr == NULL || *lineptr == 0) {
2375 if (fgets(line, sizeof(line), stdin) == NULL) { 2369 if (xmon_gets(line, sizeof(line)) == NULL) {
2376 lineptr = NULL; 2370 lineptr = NULL;
2377 return EOF; 2371 return EOF;
2378 } 2372 }
2379 lineptr = line; 2373 lineptr = line;
2380 } 2374 }
2381 return *lineptr++; 2375 return *lineptr++;
2382 } 2376 }
2383 2377
2384 void 2378 void
2385 take_input(char *str) 2379 take_input(char *str)
2386 { 2380 {
2387 lineptr = str; 2381 lineptr = str;
2388 } 2382 }
2389 2383
2390 2384
2391 static void 2385 static void
2392 symbol_lookup(void) 2386 symbol_lookup(void)
2393 { 2387 {
2394 int type = inchar(); 2388 int type = inchar();
2395 unsigned long addr; 2389 unsigned long addr;
2396 static char tmp[64]; 2390 static char tmp[64];
2397 2391
2398 switch (type) { 2392 switch (type) {
2399 case 'a': 2393 case 'a':
2400 if (scanhex(&addr)) 2394 if (scanhex(&addr))
2401 xmon_print_symbol(addr, ": ", "\n"); 2395 xmon_print_symbol(addr, ": ", "\n");
2402 termch = 0; 2396 termch = 0;
2403 break; 2397 break;
2404 case 's': 2398 case 's':
2405 getstring(tmp, 64); 2399 getstring(tmp, 64);
2406 if (setjmp(bus_error_jmp) == 0) { 2400 if (setjmp(bus_error_jmp) == 0) {
2407 catch_memory_errors = 1; 2401 catch_memory_errors = 1;
2408 sync(); 2402 sync();
2409 addr = kallsyms_lookup_name(tmp); 2403 addr = kallsyms_lookup_name(tmp);
2410 if (addr) 2404 if (addr)
2411 printf("%s: %lx\n", tmp, addr); 2405 printf("%s: %lx\n", tmp, addr);
2412 else 2406 else
2413 printf("Symbol '%s' not found.\n", tmp); 2407 printf("Symbol '%s' not found.\n", tmp);
2414 sync(); 2408 sync();
2415 } 2409 }
2416 catch_memory_errors = 0; 2410 catch_memory_errors = 0;
2417 termch = 0; 2411 termch = 0;
2418 break; 2412 break;
2419 } 2413 }
2420 } 2414 }
2421 2415
2422 2416
2423 /* Print an address in numeric and symbolic form (if possible) */ 2417 /* Print an address in numeric and symbolic form (if possible) */
2424 static void xmon_print_symbol(unsigned long address, const char *mid, 2418 static void xmon_print_symbol(unsigned long address, const char *mid,
2425 const char *after) 2419 const char *after)
2426 { 2420 {
2427 char *modname; 2421 char *modname;
2428 const char *name = NULL; 2422 const char *name = NULL;
2429 unsigned long offset, size; 2423 unsigned long offset, size;
2430 2424
2431 printf(REG, address); 2425 printf(REG, address);
2432 if (setjmp(bus_error_jmp) == 0) { 2426 if (setjmp(bus_error_jmp) == 0) {
2433 catch_memory_errors = 1; 2427 catch_memory_errors = 1;
2434 sync(); 2428 sync();
2435 name = kallsyms_lookup(address, &size, &offset, &modname, 2429 name = kallsyms_lookup(address, &size, &offset, &modname,
2436 tmpstr); 2430 tmpstr);
2437 sync(); 2431 sync();
2438 /* wait a little while to see if we get a machine check */ 2432 /* wait a little while to see if we get a machine check */
2439 __delay(200); 2433 __delay(200);
2440 } 2434 }
2441 2435
2442 catch_memory_errors = 0; 2436 catch_memory_errors = 0;
2443 2437
2444 if (name) { 2438 if (name) {
2445 printf("%s%s+%#lx/%#lx", mid, name, offset, size); 2439 printf("%s%s+%#lx/%#lx", mid, name, offset, size);
2446 if (modname) 2440 if (modname)
2447 printf(" [%s]", modname); 2441 printf(" [%s]", modname);
2448 } 2442 }
2449 printf("%s", after); 2443 printf("%s", after);
2450 } 2444 }
2451 2445
2452 #ifdef CONFIG_PPC64 2446 #ifdef CONFIG_PPC64
2453 static void dump_slb(void) 2447 static void dump_slb(void)
2454 { 2448 {
2455 int i; 2449 int i;
2456 unsigned long tmp; 2450 unsigned long tmp;
2457 2451
2458 printf("SLB contents of cpu %x\n", smp_processor_id()); 2452 printf("SLB contents of cpu %x\n", smp_processor_id());
2459 2453
2460 for (i = 0; i < SLB_NUM_ENTRIES; i++) { 2454 for (i = 0; i < SLB_NUM_ENTRIES; i++) {
2461 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i)); 2455 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i));
2462 printf("%02d %016lx ", i, tmp); 2456 printf("%02d %016lx ", i, tmp);
2463 2457
2464 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i)); 2458 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i));
2465 printf("%016lx\n", tmp); 2459 printf("%016lx\n", tmp);
2466 } 2460 }
2467 } 2461 }
2468 2462
2469 static void dump_stab(void) 2463 static void dump_stab(void)
2470 { 2464 {
2471 int i; 2465 int i;
2472 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr; 2466 unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;
2473 2467
2474 printf("Segment table contents of cpu %x\n", smp_processor_id()); 2468 printf("Segment table contents of cpu %x\n", smp_processor_id());
2475 2469
2476 for (i = 0; i < PAGE_SIZE/16; i++) { 2470 for (i = 0; i < PAGE_SIZE/16; i++) {
2477 unsigned long a, b; 2471 unsigned long a, b;
2478 2472
2479 a = *tmp++; 2473 a = *tmp++;
2480 b = *tmp++; 2474 b = *tmp++;
2481 2475
2482 if (a || b) { 2476 if (a || b) {
2483 printf("%03d %016lx ", i, a); 2477 printf("%03d %016lx ", i, a);
2484 printf("%016lx\n", b); 2478 printf("%016lx\n", b);
2485 } 2479 }
2486 } 2480 }
2487 } 2481 }
2488 2482
2489 void dump_segments(void) 2483 void dump_segments(void)
2490 { 2484 {
2491 if (cpu_has_feature(CPU_FTR_SLB)) 2485 if (cpu_has_feature(CPU_FTR_SLB))
2492 dump_slb(); 2486 dump_slb();
2493 else 2487 else
2494 dump_stab(); 2488 dump_stab();
2495 } 2489 }
2496 #endif 2490 #endif
2497 2491
2498 #ifdef CONFIG_PPC_STD_MMU_32 2492 #ifdef CONFIG_PPC_STD_MMU_32
2499 void dump_segments(void) 2493 void dump_segments(void)
2500 { 2494 {
2501 int i; 2495 int i;
2502 2496
2503 printf("sr0-15 ="); 2497 printf("sr0-15 =");
2504 for (i = 0; i < 16; ++i) 2498 for (i = 0; i < 16; ++i)
2505 printf(" %x", mfsrin(i)); 2499 printf(" %x", mfsrin(i));
2506 printf("\n"); 2500 printf("\n");
2507 } 2501 }
2508 #endif 2502 #endif
2509 2503
2510 void xmon_init(int enable) 2504 void xmon_init(int enable)
2511 { 2505 {
2512 if (enable) { 2506 if (enable) {
2513 __debugger = xmon; 2507 __debugger = xmon;
2514 __debugger_ipi = xmon_ipi; 2508 __debugger_ipi = xmon_ipi;
2515 __debugger_bpt = xmon_bpt; 2509 __debugger_bpt = xmon_bpt;
2516 __debugger_sstep = xmon_sstep; 2510 __debugger_sstep = xmon_sstep;
2517 __debugger_iabr_match = xmon_iabr_match; 2511 __debugger_iabr_match = xmon_iabr_match;
2518 __debugger_dabr_match = xmon_dabr_match; 2512 __debugger_dabr_match = xmon_dabr_match;
2519 __debugger_fault_handler = xmon_fault_handler; 2513 __debugger_fault_handler = xmon_fault_handler;
2520 } else { 2514 } else {
2521 __debugger = NULL; 2515 __debugger = NULL;
2522 __debugger_ipi = NULL; 2516 __debugger_ipi = NULL;
2523 __debugger_bpt = NULL; 2517 __debugger_bpt = NULL;
2524 __debugger_sstep = NULL; 2518 __debugger_sstep = NULL;
2525 __debugger_iabr_match = NULL; 2519 __debugger_iabr_match = NULL;
2526 __debugger_dabr_match = NULL; 2520 __debugger_dabr_match = NULL;
2527 __debugger_fault_handler = NULL; 2521 __debugger_fault_handler = NULL;
2528 } 2522 }
2523 xmon_map_scc();
2529 } 2524 }
2525
2526 #ifdef CONFIG_MAGIC_SYSRQ
2527 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
2528 struct tty_struct *tty)
2529 {
2530 /* ensure xmon is enabled */
2531 xmon_init(1);
2532 debugger(pt_regs);
2533 }
2534
2535 static struct sysrq_key_op sysrq_xmon_op =
2536 {
2537 .handler = sysrq_handle_xmon,
2538 .help_msg = "Xmon",
2539 .action_msg = "Entering xmon",
2540 };
2541
2542 static int __init setup_xmon_sysrq(void)
include/asm-powerpc/xmon.h
1 #ifndef __PPC_XMON_H 1 #ifndef __PPC_XMON_H
2 #define __PPC_XMON_H 2 #define __PPC_XMON_H
3 #ifdef __KERNEL__ 3 #ifdef __KERNEL__
4 4
5 struct pt_regs; 5 struct pt_regs;
6 6
7 extern int 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 extern void xmon_map_scc(void);
11 10
12 #endif 11 #endif
13 #endif 12 #endif
14 13