2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/kernel.h>
11 #include <linux/bootmem.h>
12 #include <linux/memblock.h>
13 #ifdef CONFIG_BLK_DEV_INITRD
14 #include <linux/initrd.h>
16 #include <linux/swap.h>
17 #include <linux/module.h>
19 #include <asm/pgalloc.h>
20 #include <asm/sections.h>
21 #include <asm/arcregs.h>
23 pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
24 char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
25 EXPORT_SYMBOL(empty_zero_page);
27 static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
28 static unsigned long low_mem_sz;
30 /* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
31 static int __init setup_mem_sz(char *str)
33 low_mem_sz = memparse(str, NULL) & PAGE_MASK;
35 /* early console might not be setup yet - it will show up later */
36 pr_info("\"mem=%s\": mem sz set to %ldM\n", str, TO_MB(low_mem_sz));
40 early_param("mem", setup_mem_sz);
42 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
45 BUG_ON(base != low_mem_start);
47 pr_info("Memory @ %llx of %ldM\n", base, TO_MB(size));
50 #ifdef CONFIG_BLK_DEV_INITRD
51 static int __init early_initrd(char *p)
53 unsigned long start, size;
56 start = memparse(p, &endp);
58 size = memparse(endp + 1, NULL);
60 initrd_start = (unsigned long)__va(start);
61 initrd_end = (unsigned long)__va(start + size);
65 early_param("initrd", early_initrd);
69 * First memory setup routine called from setup_arch()
70 * 1. setup swapper's mm @init_mm
71 * 2. Count the pages we have and setup bootmem allocator
74 void __init setup_arch_memory(void)
76 unsigned long zones_size[MAX_NR_ZONES];
78 init_mm.start_code = (unsigned long)_text;
79 init_mm.end_code = (unsigned long)_etext;
80 init_mm.end_data = (unsigned long)_edata;
81 init_mm.brk = (unsigned long)_end;
83 /* first page of system - kernel .vector starts here */
84 min_low_pfn = ARCH_PFN_OFFSET;
86 /* Last usable page of low mem */
87 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
89 max_mapnr = max_low_pfn - min_low_pfn;
91 /*------------- bootmem allocator setup -----------------------*/
92 memblock_add(low_mem_start, low_mem_sz);
93 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
95 #ifdef CONFIG_BLK_DEV_INITRD
97 memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
102 /*----------------- node/zones setup --------------------------*/
103 memset(zones_size, 0, sizeof(zones_size));
104 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
107 * We can't use the helper free_area_init(zones[]) because it uses
108 * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
109 * when our kernel doesn't start at PAGE_OFFSET, i.e.
110 * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE
112 free_area_init_node(0, /* node-id */
113 zones_size, /* num pages per zone */
114 min_low_pfn, /* first pfn of node */
115 NULL); /* NO holes */
117 high_memory = (void *)end_mem;
121 * mem_init - initializes memory
124 * Calculates and displays memory available/used
126 void __init mem_init(void)
129 mem_init_print_info(NULL);
133 * free_initmem: Free all the __init memory.
135 void __init_refok free_initmem(void)
137 free_initmem_default(-1);
140 #ifdef CONFIG_BLK_DEV_INITRD
141 void __init free_initrd_mem(unsigned long start, unsigned long end)
143 free_reserved_area((void *)start, (void *)end, -1, "initrd");