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