aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/mm/init.c')
-rw-r--r--arch/arc/mm/init.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 5487d0b97400..8be930394750 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -30,11 +30,16 @@ static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE;
30static unsigned long low_mem_sz; 30static unsigned long low_mem_sz;
31 31
32#ifdef CONFIG_HIGHMEM 32#ifdef CONFIG_HIGHMEM
33static unsigned long min_high_pfn; 33static unsigned long min_high_pfn, max_high_pfn;
34static u64 high_mem_start; 34static u64 high_mem_start;
35static u64 high_mem_sz; 35static u64 high_mem_sz;
36#endif 36#endif
37 37
38#ifdef CONFIG_DISCONTIGMEM
39struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
40EXPORT_SYMBOL(node_data);
41#endif
42
38/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */ 43/* User can over-ride above with "mem=nnn[KkMm]" in cmdline */
39static int __init setup_mem_sz(char *str) 44static int __init setup_mem_sz(char *str)
40{ 45{
@@ -109,13 +114,11 @@ void __init setup_arch_memory(void)
109 /* Last usable page of low mem */ 114 /* Last usable page of low mem */
110 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz); 115 max_low_pfn = max_pfn = PFN_DOWN(low_mem_start + low_mem_sz);
111 116
112#ifdef CONFIG_HIGHMEM 117#ifdef CONFIG_FLATMEM
113 min_high_pfn = PFN_DOWN(high_mem_start); 118 /* pfn_valid() uses this */
114 max_pfn = PFN_DOWN(high_mem_start + high_mem_sz); 119 max_mapnr = max_low_pfn - min_low_pfn;
115#endif 120#endif
116 121
117 max_mapnr = max_pfn - min_low_pfn;
118
119 /*------------- bootmem allocator setup -----------------------*/ 122 /*------------- bootmem allocator setup -----------------------*/
120 123
121 /* 124 /*
@@ -129,7 +132,7 @@ void __init setup_arch_memory(void)
129 * the crash 132 * the crash
130 */ 133 */
131 134
132 memblock_add(low_mem_start, low_mem_sz); 135 memblock_add_node(low_mem_start, low_mem_sz, 0);
133 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); 136 memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
134 137
135#ifdef CONFIG_BLK_DEV_INITRD 138#ifdef CONFIG_BLK_DEV_INITRD
@@ -149,13 +152,6 @@ void __init setup_arch_memory(void)
149 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; 152 zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
150 zones_holes[ZONE_NORMAL] = 0; 153 zones_holes[ZONE_NORMAL] = 0;
151 154
152#ifdef CONFIG_HIGHMEM
153 zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
154
155 /* This handles the peripheral address space hole */
156 zones_holes[ZONE_HIGHMEM] = min_high_pfn - max_low_pfn;
157#endif
158
159 /* 155 /*
160 * We can't use the helper free_area_init(zones[]) because it uses 156 * We can't use the helper free_area_init(zones[]) because it uses
161 * PAGE_OFFSET to compute the @min_low_pfn which would be wrong 157 * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
@@ -168,6 +164,34 @@ void __init setup_arch_memory(void)
168 zones_holes); /* holes */ 164 zones_holes); /* holes */
169 165
170#ifdef CONFIG_HIGHMEM 166#ifdef CONFIG_HIGHMEM
167 /*
168 * Populate a new node with highmem
169 *
170 * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based)
171 * than addresses in normal ala low memory (0x8000_0000 based).
172 * Even with PAE, the huge peripheral space hole would waste a lot of
173 * mem with single mem_map[]. This warrants a mem_map per region design.
174 * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM.
175 *
176 * DISCONTIGMEM in turns requires multiple nodes. node 0 above is
177 * populated with normal memory zone while node 1 only has highmem
178 */
179 node_set_online(1);
180
181 min_high_pfn = PFN_DOWN(high_mem_start);
182 max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
183
184 zones_size[ZONE_NORMAL] = 0;
185 zones_holes[ZONE_NORMAL] = 0;
186
187 zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
188 zones_holes[ZONE_HIGHMEM] = 0;
189
190 free_area_init_node(1, /* node-id */
191 zones_size, /* num pages per zone */
192 min_high_pfn, /* first pfn of node */
193 zones_holes); /* holes */
194
171 high_memory = (void *)(min_high_pfn << PAGE_SHIFT); 195 high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
172 kmap_init(); 196 kmap_init();
173#endif 197#endif
@@ -185,7 +209,7 @@ void __init mem_init(void)
185 unsigned long tmp; 209 unsigned long tmp;
186 210
187 reset_all_zones_managed_pages(); 211 reset_all_zones_managed_pages();
188 for (tmp = min_high_pfn; tmp < max_pfn; tmp++) 212 for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
189 free_highmem_page(pfn_to_page(tmp)); 213 free_highmem_page(pfn_to_page(tmp));
190#endif 214#endif
191 215