diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2006-05-17 21:16:11 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-05-19 01:02:18 -0400 |
commit | 35dd54326e857f1648c7cc1028e8d5e1dbe04992 (patch) | |
tree | dea05effa25bc751d1b777a0b80f0f46d3ff0b8e | |
parent | 473104134b35ce1c3ca77b738c561d6c215adc1b (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.c | 94 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom_init.c | 54 | ||||
-rw-r--r-- | include/asm-powerpc/kexec.h | 3 |
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 | ||
339 | static struct property crashk_base_prop = { | ||
340 | .name = "linux,crashkernel-base", | ||
341 | .length = sizeof(unsigned long), | ||
342 | .value = (unsigned char *)&crashk_res.start, | ||
343 | }; | ||
344 | |||
345 | static unsigned long crashk_size; | ||
346 | |||
347 | static struct property crashk_size_prop = { | ||
348 | .name = "linux,crashkernel-size", | ||
349 | .length = sizeof(unsigned long), | ||
350 | .value = (unsigned char *)&crashk_size, | ||
351 | }; | ||
352 | |||
353 | static 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 | |||
338 | void __init kexec_setup(void) | 381 | void __init kexec_setup(void) |
339 | { | 382 | { |
340 | export_htab_values(); | 383 | export_htab_values(); |
384 | export_crashk_values(); | ||
385 | } | ||
386 | |||
387 | static 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 | } | ||
405 | early_param("crashkernel", early_parse_crashk); | ||
406 | |||
407 | void __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 | ||
343 | int overlaps_crashkernel(unsigned long start, unsigned long size) | 437 | int 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; | |||
200 | static unsigned long __initdata rmo_top; | 200 | static unsigned long __initdata rmo_top; |
201 | static unsigned long __initdata ram_top; | 201 | static unsigned long __initdata ram_top; |
202 | 202 | ||
203 | #ifdef CONFIG_KEXEC | ||
204 | static unsigned long __initdata prom_crashk_base; | ||
205 | static unsigned long __initdata prom_crashk_size; | ||
206 | #endif | ||
207 | |||
208 | static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; | 203 | static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; |
209 | static int __initdata mem_reserve_cnt; | 204 | static 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 | ||
126 | extern void machine_kexec_simple(struct kimage *image); | 126 | extern void machine_kexec_simple(struct kimage *image); |
127 | extern int overlaps_crashkernel(unsigned long start, unsigned long size); | 127 | extern int overlaps_crashkernel(unsigned long start, unsigned long size); |
128 | extern 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 | ||
137 | static 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__ */ |