X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Fpowerpc%2Fkernel%2Fmachine_kexec.c;h=2d202f274e7384722a0584a224b415420ee5ed11;hb=745a14cc264b1832c638e41812e0cb04328b2db1;hp=a81ca1b841ec89a0c5eff398b676dac5a3ae85fc;hpb=bf785ee0aeea7a3e717cb1e11df4135b6cbde7da;p=linux-2.6-omap-h63xx.git diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index a81ca1b841e..2d202f274e7 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include void machine_crash_shutdown(struct pt_regs *regs) { @@ -59,3 +61,58 @@ NORET_TYPE void machine_kexec(struct kimage *image) } for(;;); } + +void __init reserve_crashkernel(void) +{ + unsigned long long crash_size, crash_base; + int ret; + + /* this is necessary because of lmb_phys_mem_size() */ + lmb_analyze(); + + /* use common parsing */ + ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(), + &crash_size, &crash_base); + if (ret == 0 && crash_size > 0) { + if (crash_base == 0) + crash_base = KDUMP_KERNELBASE; + crashk_res.start = crash_base; + } else { + /* handle the device tree */ + crash_size = crashk_res.end - crashk_res.start + 1; + } + + if (crash_size == 0) + return; + + /* We might have got these values via the command line or the + * device tree, either way sanitise them now. */ + + if (crashk_res.start != KDUMP_KERNELBASE) + printk("Crash kernel location must be 0x%x\n", + KDUMP_KERNELBASE); + + crashk_res.start = KDUMP_KERNELBASE; + crash_size = PAGE_ALIGN(crash_size); + crashk_res.end = crashk_res.start + crash_size - 1; + + /* Crash kernel trumps memory limit */ + if (memory_limit && memory_limit <= crashk_res.end) { + memory_limit = crashk_res.end + 1; + printk("Adjusted memory limit for crashkernel, now 0x%lx\n", + memory_limit); + } + + printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " + "for crashkernel (System RAM: %ldMB)\n", + (unsigned long)(crash_size >> 20), + (unsigned long)(crashk_res.start >> 20), + (unsigned long)(lmb_phys_mem_size() >> 20)); + + lmb_reserve(crashk_res.start, crash_size); +} + +int overlaps_crashkernel(unsigned long start, unsigned long size) +{ + return (start + size) > crashk_res.start && start <= crashk_res.end; +}