diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2012-10-11 18:14:58 +0200 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2012-12-13 16:46:47 +0100 |
commit | 7aa1c8f47e7e792d11f898cbdddaf6fa21ff08cc (patch) | |
tree | e34986c087ab7a9f91c8303eda7f13736e315905 /arch/mips/kernel/setup.c | |
parent | 98cdee0eae861e8d25c147a72c5f309e883f4ed8 (diff) |
MIPS: kdump: Add support
[ralf@linux-mips.org: Original patch by Maxim Uvarov <muvarov@gmail.com>
with plenty of further shining, polishing, debugging and testing by me.]
Signed-off-by: Maxim Uvarov <muvarov@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: kexec@lists.infradead.org
Cc: horms@verge.net.au
Patchwork: https://patchwork.linux-mips.org/patch/1025/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/setup.c')
-rw-r--r-- | arch/mips/kernel/setup.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 290dc6a1d7a..8c41187801c 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -22,6 +22,7 @@ #include <linux/console.h> #include <linux/pfn.h> #include <linux/debugfs.h> +#include <linux/kexec.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> @@ -536,12 +537,64 @@ static void __init arch_mem_init(char **cmdline_p) } bootmem_init(); +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1, + BOOTMEM_DEFAULT); +#endif device_tree_init(); sparse_init(); plat_swiotlb_setup(); paging_init(); } +#ifdef CONFIG_KEXEC +static inline unsigned long long get_total_mem(void) +{ + unsigned long long total; + + total = max_pfn - min_low_pfn; + return total << PAGE_SHIFT; +} + +static void __init mips_parse_crashkernel(void) +{ + unsigned long long total_mem; + unsigned long long crash_size, crash_base; + int ret; + + total_mem = get_total_mem(); + ret = parse_crashkernel(boot_command_line, total_mem, + &crash_size, &crash_base); + if (ret != 0 || crash_size <= 0) + return; + + crashk_res.start = crash_base; + crashk_res.end = crash_base + crash_size - 1; +} + +static void __init request_crashkernel(struct resource *res) +{ + int ret; + + ret = request_resource(res, &crashk_res); + if (!ret) + pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n", + (unsigned long)((crashk_res.end - + crashk_res.start + 1) >> 20), + (unsigned long)(crashk_res.start >> 20)); +} +#else /* !defined(CONFIG_KEXEC) */ +static void __init mips_parse_crashkernel(void) +{ +} + +static void __init request_crashkernel(struct resource *res) +{ +} +#endif /* !defined(CONFIG_KEXEC) */ + static void __init resource_init(void) { int i; @@ -557,6 +610,8 @@ static void __init resource_init(void) /* * Request address space for all standard RAM. */ + mips_parse_crashkernel(); + for (i = 0; i < boot_mem_map.nr_map; i++) { struct resource *res; unsigned long start, end; @@ -593,6 +648,7 @@ static void __init resource_init(void) */ request_resource(res, &code_resource); request_resource(res, &data_resource); + request_crashkernel(res); } } |