Commit b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2

Authored by Olaf Hering
Committed by Paul Mackerras
1 parent bef5686229

[PATCH] ppc64: allow xmon=off

If both CONFIG_XMON and CONFIG_XMON_DEFAULT is enabled in the .config,
there is no way to disable xmon again. setup_system calls first xmon_init,
later parse_early_param. So a new 'xmon=off' cmdline option will do the right
thing.

Signed-off-by: Olaf Hering <olh@suse.de>
Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 4 changed files with 26 additions and 14 deletions Inline Diff

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