summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/setup.c')
-rw-r--r--arch/mips/kernel/setup.c91
1 files changed, 70 insertions, 21 deletions
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 653197e151d5..4c774d5d5087 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -480,34 +480,75 @@ static int __init early_parse_mem(char *p)
}
early_param("mem", early_parse_mem);
-static void __init arch_mem_init(char **cmdline_p)
+#ifdef CONFIG_PROC_VMCORE
+unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
+static int __init early_parse_elfcorehdr(char *p)
+{
+ int i;
+
+ setup_elfcorehdr = memparse(p, &p);
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long start = boot_mem_map.map[i].addr;
+ unsigned long end = (boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+ if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
+ /*
+ * Reserve from the elf core header to the end of
+ * the memory segment, that should all be kdump
+ * reserved memory.
+ */
+ setup_elfcorehdr_size = end - setup_elfcorehdr;
+ break;
+ }
+ }
+ /*
+ * If we don't find it in the memory map, then we shouldn't
+ * have to worry about it, as the new kernel won't use it.
+ */
+ return 0;
+}
+early_param("elfcorehdr", early_parse_elfcorehdr);
+#endif
+
+static void __init arch_mem_addpart(phys_t mem, phys_t end, int type)
{
- phys_t init_mem, init_end, init_size;
+ phys_t size;
+ int i;
+ size = end - mem;
+ if (!size)
+ return;
+
+ /* Make sure it is in the boot_mem_map */
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (mem >= boot_mem_map.map[i].addr &&
+ mem < (boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size))
+ return;
+ }
+ add_memory_region(mem, size, type);
+}
+
+static void __init arch_mem_init(char **cmdline_p)
+{
extern void plat_mem_setup(void);
/* call board setup routine */
plat_mem_setup();
- init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT;
- init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT;
- init_size = init_end - init_mem;
- if (init_size) {
- /* Make sure it is in the boot_mem_map */
- int i, found;
- found = 0;
- for (i = 0; i < boot_mem_map.nr_map; i++) {
- if (init_mem >= boot_mem_map.map[i].addr &&
- init_mem < (boot_mem_map.map[i].addr +
- boot_mem_map.map[i].size)) {
- found = 1;
- break;
- }
- }
- if (!found)
- add_memory_region(init_mem, init_size,
- BOOT_MEM_INIT_RAM);
- }
+ /*
+ * Make sure all kernel memory is in the maps. The "UP" and
+ * "DOWN" are opposite for initdata since if it crosses over
+ * into another memory section you don't want that to be
+ * freed when the initdata is freed.
+ */
+ arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
+ PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
+ BOOT_MEM_RAM);
+ arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
+ PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
+ BOOT_MEM_INIT_RAM);
pr_info("Determined physical RAM map:\n");
print_memory_map();
@@ -537,6 +578,14 @@ static void __init arch_mem_init(char **cmdline_p)
}
bootmem_init();
+#ifdef CONFIG_PROC_VMCORE
+ if (setup_elfcorehdr && setup_elfcorehdr_size) {
+ printk(KERN_INFO "kdump reserved memory at %lx-%lx\n",
+ setup_elfcorehdr, setup_elfcorehdr_size);
+ reserve_bootmem(setup_elfcorehdr, setup_elfcorehdr_size,
+ BOOTMEM_DEFAULT);
+ }
+#endif
#ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start,