1
2
3
4
5
6
7
8
9#include <linux/kernel.h>
10#include <linux/mm.h>
11#include <linux/memblock.h>
12#ifdef CONFIG_BLK_DEV_INITRD
13#include <linux/initrd.h>
14#endif
15#include <linux/of_fdt.h>
16#include <linux/swap.h>
17#include <linux/module.h>
18#include <linux/highmem.h>
19#include <asm/page.h>
20#include <asm/pgalloc.h>
21#include <asm/sections.h>
22#include <asm/arcregs.h>
23
24pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE);
25char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE);
26EXPORT_SYMBOL(empty_zero_page);
27
28static const unsigned long low_mem_start = CONFIG_LINUX_RAM_BASE;
29static unsigned long low_mem_sz;
30
31#ifdef CONFIG_HIGHMEM
32static unsigned long min_high_pfn, max_high_pfn;
33static u64 high_mem_start;
34static u64 high_mem_sz;
35#endif
36
37#ifdef CONFIG_DISCONTIGMEM
38struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
39EXPORT_SYMBOL(node_data);
40#endif
41
42long __init arc_get_mem_sz(void)
43{
44 return low_mem_sz;
45}
46
47
48static int __init setup_mem_sz(char *str)
49{
50 low_mem_sz = memparse(str, NULL) & PAGE_MASK;
51
52
53 pr_info("\"mem=%s\": mem sz set to %ldM\n", str, TO_MB(low_mem_sz));
54
55 return 0;
56}
57early_param("mem", setup_mem_sz);
58
59void __init early_init_dt_add_memory_arch(u64 base, u64 size)
60{
61 int in_use = 0;
62
63 if (!low_mem_sz) {
64 if (base != low_mem_start)
65 panic("CONFIG_LINUX_RAM_BASE != DT memory { }");
66
67 low_mem_sz = size;
68 in_use = 1;
69 } else {
70#ifdef CONFIG_HIGHMEM
71 high_mem_start = base;
72 high_mem_sz = size;
73 in_use = 1;
74#endif
75 }
76
77 pr_info("Memory @ %llx [%lldM] %s\n",
78 base, TO_MB(size), !in_use ? "Not used":"");
79}
80
81#ifdef CONFIG_BLK_DEV_INITRD
82static int __init early_initrd(char *p)
83{
84 unsigned long start, size;
85 char *endp;
86
87 start = memparse(p, &endp);
88 if (*endp == ',') {
89 size = memparse(endp + 1, NULL);
90
91 initrd_start = (unsigned long)__va(start);
92 initrd_end = (unsigned long)__va(start + size);
93 }
94 return 0;
95}
96early_param("initrd", early_initrd);
97#endif
98
99
100
101
102
103
104
105void __init setup_arch_memory(void)
106{
107 unsigned long zones_size[MAX_NR_ZONES];
108 unsigned long zones_holes[MAX_NR_ZONES];
109
110 init_mm.start_code = (unsigned long)_text;
111 init_mm.end_code = (unsigned long)_etext;
112 init_mm.end_data = (unsigned long)_edata;
113 init_mm.brk = (unsigned long)_end;
114
115
116 min_low_pfn = ARCH_PFN_OFFSET;
117
118
119 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
120
121#ifdef CONFIG_FLATMEM
122
123 max_mapnr = max_low_pfn - min_low_pfn;
124#endif
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 memblock_add_node(low_mem_start, low_mem_sz, 0);
140 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
141
142#ifdef CONFIG_BLK_DEV_INITRD
143 if (initrd_start)
144 memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
145#endif
146
147 early_init_fdt_reserve_self();
148 early_init_fdt_scan_reserved_mem();
149
150 memblock_dump_all();
151
152
153 memset(zones_size, 0, sizeof(zones_size));
154 memset(zones_holes, 0, sizeof(zones_holes));
155
156 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
157 zones_holes[ZONE_NORMAL] = 0;
158
159
160
161
162
163
164
165 free_area_init_node(0,
166 zones_size,
167 min_low_pfn,
168 zones_holes);
169
170#ifdef CONFIG_HIGHMEM
171
172
173
174
175
176
177
178
179
180
181
182
183 node_set_online(1);
184
185 min_high_pfn = PFN_DOWN(high_mem_start);
186 max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
187
188 zones_size[ZONE_NORMAL] = 0;
189 zones_holes[ZONE_NORMAL] = 0;
190
191 zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
192 zones_holes[ZONE_HIGHMEM] = 0;
193
194 free_area_init_node(1,
195 zones_size,
196 min_high_pfn,
197 zones_holes);
198
199 high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
200 kmap_init();
201#endif
202}
203
204
205
206
207
208
209
210void __init mem_init(void)
211{
212#ifdef CONFIG_HIGHMEM
213 unsigned long tmp;
214
215 reset_all_zones_managed_pages();
216 for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
217 free_highmem_page(pfn_to_page(tmp));
218#endif
219
220 memblock_free_all();
221 mem_init_print_info(NULL);
222}
223
224
225
226
227void __ref free_initmem(void)
228{
229 free_initmem_default(-1);
230}
231
232#ifdef CONFIG_BLK_DEV_INITRD
233void __init free_initrd_mem(unsigned long start, unsigned long end)
234{
235 free_reserved_area((void *)start, (void *)end, -1, "initrd");
236}
237#endif
238