X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=arch%2Fpowerpc%2Fkernel%2Fmachine_kexec.c;h=c0c8e8c3ced90a62b8c5996dcd75bb1a6bae0001;hp=a81ca1b841ec89a0c5eff398b676dac5a3ae85fc;hb=81f8320f624a785d77443ace83391d0fdee695f6;hpb=9fdb62af92c741addbea15545f214a6e89460865 diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index a81ca1b841ec..c0c8e8c3ced9 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -13,6 +13,7 @@ #include #include #include +#include void machine_crash_shutdown(struct pt_regs *regs) { @@ -59,3 +60,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; +}