aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2006-05-17 21:16:11 -0400
committerPaul Mackerras <paulus@samba.org>2006-05-19 01:02:18 -0400
commit35dd54326e857f1648c7cc1028e8d5e1dbe04992 (patch)
treedea05effa25bc751d1b777a0b80f0f46d3ff0b8e
parent473104134b35ce1c3ca77b738c561d6c215adc1b (diff)
[PATCH] powerpc: Move crashkernel= handling into the kernel.
This was missing a quilt ref. Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c94
-rw-r--r--arch/powerpc/kernel/prom.c1
-rw-r--r--arch/powerpc/kernel/prom_init.c54
-rw-r--r--include/asm-powerpc/kexec.h3
4 files changed, 98 insertions, 54 deletions
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 1ccb188ba40d..a8fa04ef27cd 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -21,6 +21,7 @@
21#include <asm/machdep.h> 21#include <asm/machdep.h>
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <asm/paca.h> 23#include <asm/paca.h>
24#include <asm/lmb.h>
24#include <asm/mmu.h> 25#include <asm/mmu.h>
25#include <asm/sections.h> /* _end */ 26#include <asm/sections.h> /* _end */
26#include <asm/prom.h> 27#include <asm/prom.h>
@@ -335,9 +336,102 @@ static void __init export_htab_values(void)
335 of_node_put(node); 336 of_node_put(node);
336} 337}
337 338
339static struct property crashk_base_prop = {
340 .name = "linux,crashkernel-base",
341 .length = sizeof(unsigned long),
342 .value = (unsigned char *)&crashk_res.start,
343};
344
345static unsigned long crashk_size;
346
347static struct property crashk_size_prop = {
348 .name = "linux,crashkernel-size",
349 .length = sizeof(unsigned long),
350 .value = (unsigned char *)&crashk_size,
351};
352
353static void __init export_crashk_values(void)
354{
355 struct device_node *node;
356 struct property *prop;
357
358 node = of_find_node_by_path("/chosen");
359 if (!node)
360 return;
361
362 /* There might be existing crash kernel properties, but we can't
363 * be sure what's in them, so remove them. */
364 prop = of_find_property(node, "linux,crashkernel-base", NULL);
365 if (prop)
366 prom_remove_property(node, prop);
367
368 prop = of_find_property(node, "linux,crashkernel-size", NULL);
369 if (prop)
370 prom_remove_property(node, prop);
371
372 if (crashk_res.start != 0) {
373 prom_add_property(node, &crashk_base_prop);
374 crashk_size = crashk_res.end - crashk_res.start + 1;
375 prom_add_property(node, &crashk_size_prop);
376 }
377
378 of_node_put(node);
379}
380
338void __init kexec_setup(void) 381void __init kexec_setup(void)
339{ 382{
340 export_htab_values(); 383 export_htab_values();
384 export_crashk_values();
385}
386
387static int __init early_parse_crashk(char *p)
388{
389 unsigned long size;
390
391 if (!p)
392 return 1;
393
394 size = memparse(p, &p);
395
396 if (*p == '@')
397 crashk_res.start = memparse(p + 1, &p);
398 else
399 crashk_res.start = KDUMP_KERNELBASE;
400
401 crashk_res.end = crashk_res.start + size - 1;
402
403 return 0;
404}
405early_param("crashkernel", early_parse_crashk);
406
407void __init reserve_crashkernel(void)
408{
409 unsigned long size;
410
411 if (crashk_res.start == 0)
412 return;
413
414 /* We might have got these values via the command line or the
415 * device tree, either way sanitise them now. */
416
417 size = crashk_res.end - crashk_res.start + 1;
418
419 if (crashk_res.start != KDUMP_KERNELBASE)
420 printk("Crash kernel location must be 0x%x\n",
421 KDUMP_KERNELBASE);
422
423 crashk_res.start = KDUMP_KERNELBASE;
424 size = PAGE_ALIGN(size);
425 crashk_res.end = crashk_res.start + size - 1;
426
427 /* Crash kernel trumps memory limit */
428 if (memory_limit && memory_limit <= crashk_res.end) {
429 memory_limit = crashk_res.end + 1;
430 printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
431 memory_limit);
432 }
433
434 lmb_reserve(crashk_res.start, size);
341} 435}
342 436
343int overlaps_crashkernel(unsigned long start, unsigned long size) 437int overlaps_crashkernel(unsigned long start, unsigned long size)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 2498afeef291..8d0415b080bb 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1327,6 +1327,7 @@ void __init early_init_devtree(void *params)
1327 /* Reserve LMB regions used by kernel, initrd, dt, etc... */ 1327 /* Reserve LMB regions used by kernel, initrd, dt, etc... */
1328 lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); 1328 lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
1329 reserve_kdump_trampoline(); 1329 reserve_kdump_trampoline();
1330 reserve_crashkernel();
1330 early_reserve_mem(); 1331 early_reserve_mem();
1331 1332
1332 lmb_enforce_memory_limit(memory_limit); 1333 lmb_enforce_memory_limit(memory_limit);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index a52377c68fc6..2442361772e2 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -200,11 +200,6 @@ static unsigned long __initdata alloc_bottom;
200static unsigned long __initdata rmo_top; 200static unsigned long __initdata rmo_top;
201static unsigned long __initdata ram_top; 201static unsigned long __initdata ram_top;
202 202
203#ifdef CONFIG_KEXEC
204static unsigned long __initdata prom_crashk_base;
205static unsigned long __initdata prom_crashk_size;
206#endif
207
208static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; 203static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
209static int __initdata mem_reserve_cnt; 204static int __initdata mem_reserve_cnt;
210 205
@@ -591,35 +586,6 @@ static void __init early_cmdline_parse(void)
591 RELOC(iommu_force_on) = 1; 586 RELOC(iommu_force_on) = 1;
592 } 587 }
593#endif 588#endif
594
595#ifdef CONFIG_KEXEC
596 /*
597 * crashkernel=size@addr specifies the location to reserve for
598 * crash kernel.
599 */
600 opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
601 if (opt) {
602 opt += 12;
603 RELOC(prom_crashk_size) =
604 prom_memparse(opt, (const char **)&opt);
605
606 if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
607 RELOC(prom_crashk_size)) {
608 prom_printf("Warning: crashkernel size is not "
609 "aligned to 16MB\n");
610 }
611
612 /*
613 * At present, the crash kernel always run at 32MB.
614 * Just ignore whatever user passed.
615 */
616 RELOC(prom_crashk_base) = 0x2000000;
617 if (*opt == '@') {
618 prom_printf("Warning: PPC64 kdump kernel always runs "
619 "at 32 MB\n");
620 }
621 }
622#endif
623} 589}
624 590
625#ifdef CONFIG_PPC_PSERIES 591#ifdef CONFIG_PPC_PSERIES
@@ -1122,12 +1088,6 @@ static void __init prom_init_mem(void)
1122 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); 1088 prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high));
1123 prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); 1089 prom_printf(" rmo_top : %x\n", RELOC(rmo_top));
1124 prom_printf(" ram_top : %x\n", RELOC(ram_top)); 1090 prom_printf(" ram_top : %x\n", RELOC(ram_top));
1125#ifdef CONFIG_KEXEC
1126 if (RELOC(prom_crashk_base)) {
1127 prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base));
1128 prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size));
1129 }
1130#endif
1131} 1091}
1132 1092
1133 1093
@@ -2187,10 +2147,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2187 */ 2147 */
2188 prom_init_mem(); 2148 prom_init_mem();
2189 2149
2190#ifdef CONFIG_KEXEC
2191 if (RELOC(prom_crashk_base))
2192 reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
2193#endif
2194 /* 2150 /*
2195 * Determine which cpu is actually running right _now_ 2151 * Determine which cpu is actually running right _now_
2196 */ 2152 */
@@ -2243,16 +2199,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2243 } 2199 }
2244#endif 2200#endif
2245 2201
2246#ifdef CONFIG_KEXEC
2247 if (RELOC(prom_crashk_base)) {
2248 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
2249 PTRRELOC(&prom_crashk_base),
2250 sizeof(RELOC(prom_crashk_base)));
2251 prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
2252 PTRRELOC(&prom_crashk_size),
2253 sizeof(RELOC(prom_crashk_size)));
2254 }
2255#endif
2256 /* 2202 /*
2257 * Fixup any known bugs in the device-tree 2203 * Fixup any known bugs in the device-tree
2258 */ 2204 */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 0a1afced173f..efe8872ec583 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -125,6 +125,7 @@ extern void default_machine_crash_shutdown(struct pt_regs *regs);
125 125
126extern void machine_kexec_simple(struct kimage *image); 126extern void machine_kexec_simple(struct kimage *image);
127extern int overlaps_crashkernel(unsigned long start, unsigned long size); 127extern int overlaps_crashkernel(unsigned long start, unsigned long size);
128extern void reserve_crashkernel(void);
128 129
129#else /* !CONFIG_KEXEC */ 130#else /* !CONFIG_KEXEC */
130 131
@@ -133,6 +134,8 @@ static inline int overlaps_crashkernel(unsigned long start, unsigned long size)
133 return 0; 134 return 0;
134} 135}
135 136
137static inline void reserve_crashkernel(void) { ; }
138
136#endif /* CONFIG_KEXEC */ 139#endif /* CONFIG_KEXEC */
137#endif /* ! __ASSEMBLY__ */ 140#endif /* ! __ASSEMBLY__ */
138#endif /* __KERNEL__ */ 141#endif /* __KERNEL__ */