crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1);
if (!crashk_res.start) {
- crashk_res.start = lmb_alloc(crash_size, PAGE_SIZE);
+ unsigned long max = lmb_end_of_DRAM() - memory_limit;
+ crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max);
if (!crashk_res.start) {
pr_err("crashkernel allocation failed\n");
goto disable;
}
}
- pr_info("Reserving %ldMB of memory at %ldMB "
+ crashk_res.end = crashk_res.start + crash_size - 1;
+
+ /*
+ * Crash kernel trumps memory limit
+ */
+ if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) {
+ memory_limit = 0;
+ pr_info("Disabled memory limit for crashkernel\n");
+ }
+
+ pr_info("Reserving %ldMB of memory at 0x%08lx "
"for crashkernel (System RAM: %ldMB)\n",
(unsigned long)(crash_size >> 20),
- (unsigned long)(crashk_res.start >> 20),
+ (unsigned long)(crashk_res.start),
(unsigned long)(lmb_phys_mem_size() >> 20));
- crashk_res.end = crashk_res.start + crash_size - 1;
- insert_resource(&iomem_resource, &crashk_res);
-
return;
disable:
EXPORT_SYMBOL(memory_start);
unsigned long memory_end = 0;
EXPORT_SYMBOL(memory_end);
+unsigned long memory_limit = 0;
static struct resource mem_resources[MAX_NUMNODES];
static int __init early_parse_mem(char *p)
{
- unsigned long size;
+ if (!p)
+ return 1;
- memory_start = (unsigned long)__va(__MEMORY_START);
- size = memparse(p, &p);
-
- if (size > __MEMORY_SIZE) {
- printk(KERN_ERR
- "Using mem= to increase the size of kernel memory "
- "is not allowed.\n"
- " Recompile the kernel with the correct value for "
- "CONFIG_MEMORY_SIZE.\n");
- return 0;
- }
+ memory_limit = PAGE_ALIGN(memparse(p, &p));
- memory_end = memory_start + size;
+ pr_notice("Memory limited to %ldMB\n", memory_limit >> 20);
return 0;
}
{
unsigned long bootmap_size;
unsigned long bootmap_pages, bootmem_paddr;
- u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
+ u64 total_pages = lmb_phys_mem_size() >> PAGE_SHIFT;
int i;
bootmap_pages = bootmem_bootmap_pages(total_pages);
__add_active_range(0, start_pfn, end_pfn);
}
- /*
- * Handle additional early reservations
- */
- check_for_initrd();
- reserve_crashkernel();
-
/*
* Add all physical memory to the bootmem map and mark each
* area as present.
sparse_memory_present_with_active_regions(0);
}
-static void __init setup_memory(void)
+static void __init early_reserve_mem(void)
{
unsigned long start_pfn;
if (CONFIG_ZERO_PAGE_OFFSET != 0)
lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
- lmb_analyze();
- lmb_dump_all();
-
- do_init_bootmem();
- plat_mem_setup();
+ /*
+ * Handle additional early reservations
+ */
+ check_for_initrd();
+ reserve_crashkernel();
}
/*
bss_resource.start = virt_to_phys(__bss_start);
bss_resource.end = virt_to_phys(_ebss)-1;
- memory_start = (unsigned long)__va(__MEMORY_START);
- if (!memory_end)
- memory_end = memory_start + __MEMORY_SIZE;
-
#ifdef CONFIG_CMDLINE_OVERWRITE
strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
#else
parse_early_param();
- uncached_init();
-
plat_early_device_setup();
/* Let earlyprintk output early console messages */
sh_mv_setup();
sh_mv.mv_mem_init();
- /*
- * Find the highest page frame number we have available
- */
- max_pfn = PFN_DOWN(__pa(memory_end));
+ early_reserve_mem();
+
+ lmb_enforce_memory_limit(memory_limit);
+ lmb_analyze();
+
+ lmb_dump_all();
/*
* Determine low and high memory ranges:
*/
- max_low_pfn = max_pfn;
+ max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
nodes_clear(node_online_map);
+ memory_start = (unsigned long)__va(__MEMORY_START);
+ memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size());
+
+ uncached_init();
pmb_init();
- setup_memory();
+ do_init_bootmem();
+ plat_mem_setup();
sparse_init();
#ifdef CONFIG_DUMMY_CONSOLE