aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/setup.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-03-28 03:38:13 -0400
committerPaul Mundt <lethal@hera.kernel.org>2007-05-06 22:10:54 -0400
commit01066625e9ae39742c92e21163f7f2a818e02762 (patch)
treec5b8a2a2c9de29ed13094891fce2b7f5769ffca7 /arch/sh/kernel/setup.c
parent759ab068c4d4216c4ad247bfa851601dfb6500dc (diff)
sh: bootmem tidying for discontig/sparsemem preparation.
This reworks some of the node 0 bootmem initialization in preparation for discontigmem and sparsemem support. ARCH_POPULATES_NODE_MAP is switched to as a result of this. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/setup.c')
-rw-r--r--arch/sh/kernel/setup.c164
1 files changed, 95 insertions, 69 deletions
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 4d6d89115194..60cc2161438f 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -4,7 +4,7 @@
4 * This file handles the architecture-dependent parts of initialization 4 * This file handles the architecture-dependent parts of initialization
5 * 5 *
6 * Copyright (C) 1999 Niibe Yutaka 6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 - 2006 Paul Mundt 7 * Copyright (C) 2002 - 2007 Paul Mundt
8 */ 8 */
9#include <linux/screen_info.h> 9#include <linux/screen_info.h>
10#include <linux/ioport.h> 10#include <linux/ioport.h>
@@ -15,15 +15,18 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/root_dev.h> 16#include <linux/root_dev.h>
17#include <linux/utsname.h> 17#include <linux/utsname.h>
18#include <linux/nodemask.h>
18#include <linux/cpu.h> 19#include <linux/cpu.h>
19#include <linux/pfn.h> 20#include <linux/pfn.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/mm.h>
21#include <asm/uaccess.h> 23#include <asm/uaccess.h>
22#include <asm/io.h> 24#include <asm/io.h>
23#include <asm/sections.h> 25#include <asm/sections.h>
24#include <asm/irq.h> 26#include <asm/irq.h>
25#include <asm/setup.h> 27#include <asm/setup.h>
26#include <asm/clock.h> 28#include <asm/clock.h>
29#include <asm/mmu_context.h>
27 30
28extern void * __rd_start, * __rd_end; 31extern void * __rd_start, * __rd_end;
29 32
@@ -202,53 +205,33 @@ static int __init sh_mv_setup(char **cmdline_p)
202 return 0; 205 return 0;
203} 206}
204 207
205void __init setup_arch(char **cmdline_p) 208/*
209 * Register fully available low RAM pages with the bootmem allocator.
210 */
211static void __init register_bootmem_low_pages(void)
206{ 212{
207 unsigned long bootmap_size; 213 unsigned long curr_pfn, last_pfn, pages;
208 unsigned long start_pfn, max_pfn, max_low_pfn;
209
210#ifdef CONFIG_CMDLINE_BOOL
211 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
212#endif
213
214 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
215
216#ifdef CONFIG_BLK_DEV_RAM
217 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
218 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
219 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
220#endif
221
222 if (!MOUNT_ROOT_RDONLY)
223 root_mountflags &= ~MS_RDONLY;
224 init_mm.start_code = (unsigned long) _text;
225 init_mm.end_code = (unsigned long) _etext;
226 init_mm.end_data = (unsigned long) _edata;
227 init_mm.brk = (unsigned long) _end;
228
229 code_resource.start = (unsigned long)virt_to_phys(_text);
230 code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
231 data_resource.start = (unsigned long)virt_to_phys(_etext);
232 data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
233
234 sh_mv_setup(cmdline_p);
235
236 214
237 /* 215 /*
238 * Find the highest page frame number we have available 216 * We are rounding up the start address of usable memory:
239 */ 217 */
240 max_pfn = PFN_DOWN(__pa(memory_end)); 218 curr_pfn = PFN_UP(__MEMORY_START);
241 219
242 /* 220 /*
243 * Determine low and high memory ranges: 221 * ... and at the end of the usable range downwards:
244 */ 222 */
245 max_low_pfn = max_pfn; 223 last_pfn = PFN_DOWN(__pa(memory_end));
246 224
247 /* 225 if (last_pfn > max_low_pfn)
248 * Partially used pages are not usable - thus 226 last_pfn = max_low_pfn;
249 * we are rounding upwards: 227
250 */ 228 pages = last_pfn - curr_pfn;
251 start_pfn = PFN_UP(__pa(_end)); 229 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
230}
231
232void __init setup_bootmem_allocator(unsigned long start_pfn)
233{
234 unsigned long bootmap_size;
252 235
253 /* 236 /*
254 * Find a proper area for the bootmem bitmap. After this 237 * Find a proper area for the bootmem bitmap. After this
@@ -256,31 +239,11 @@ void __init setup_arch(char **cmdline_p)
256 * is intact) must be done via bootmem_alloc(). 239 * is intact) must be done via bootmem_alloc().
257 */ 240 */
258 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, 241 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
259 __MEMORY_START>>PAGE_SHIFT, 242 min_low_pfn, max_low_pfn);
260 max_low_pfn);
261 /*
262 * Register fully available low RAM pages with the bootmem allocator.
263 */
264 {
265 unsigned long curr_pfn, last_pfn, pages;
266
267 /*
268 * We are rounding up the start address of usable memory:
269 */
270 curr_pfn = PFN_UP(__MEMORY_START);
271 /*
272 * ... and at the end of the usable range downwards:
273 */
274 last_pfn = PFN_DOWN(__pa(memory_end));
275 243
276 if (last_pfn > max_low_pfn) 244 register_bootmem_low_pages();
277 last_pfn = max_low_pfn;
278
279 pages = last_pfn - curr_pfn;
280 free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
281 PFN_PHYS(pages));
282 }
283 245
246 node_set_online(0);
284 247
285 /* 248 /*
286 * Reserve the kernel text and 249 * Reserve the kernel text and
@@ -289,14 +252,14 @@ void __init setup_arch(char **cmdline_p)
289 * case of us accidentally initializing the bootmem allocator with 252 * case of us accidentally initializing the bootmem allocator with
290 * an invalid RAM area. 253 * an invalid RAM area.
291 */ 254 */
292 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE, 255 reserve_bootmem(__MEMORY_START+PAGE_SIZE,
293 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); 256 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
294 257
295 /* 258 /*
296 * reserve physical page 0 - it's a special BIOS page on many boxes, 259 * reserve physical page 0 - it's a special BIOS page on many boxes,
297 * enabling clean reboots, SMP operation, laptop functions. 260 * enabling clean reboots, SMP operation, laptop functions.
298 */ 261 */
299 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); 262 reserve_bootmem(__MEMORY_START, PAGE_SIZE);
300 263
301#ifdef CONFIG_BLK_DEV_INITRD 264#ifdef CONFIG_BLK_DEV_INITRD
302 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); 265 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -310,8 +273,8 @@ void __init setup_arch(char **cmdline_p)
310 273
311 if (LOADER_TYPE && INITRD_START) { 274 if (LOADER_TYPE && INITRD_START) {
312 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { 275 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
313 reserve_bootmem_node(NODE_DATA(0), INITRD_START + 276 reserve_bootmem(INITRD_START + __MEMORY_START,
314 __MEMORY_START, INITRD_SIZE); 277 INITRD_SIZE);
315 initrd_start = INITRD_START + PAGE_OFFSET + 278 initrd_start = INITRD_START + PAGE_OFFSET +
316 __MEMORY_START; 279 __MEMORY_START;
317 initrd_end = initrd_start + INITRD_SIZE; 280 initrd_end = initrd_start + INITRD_SIZE;
@@ -324,6 +287,71 @@ void __init setup_arch(char **cmdline_p)
324 } 287 }
325 } 288 }
326#endif 289#endif
290}
291
292#ifndef CONFIG_NEED_MULTIPLE_NODES
293static void __init setup_memory(void)
294{
295 unsigned long start_pfn;
296
297 /*
298 * Partially used pages are not usable - thus
299 * we are rounding upwards:
300 */
301 start_pfn = PFN_UP(__pa(_end));
302 setup_bootmem_allocator(start_pfn);
303}
304#else
305extern void __init setup_memory(void);
306#endif
307
308void __init setup_arch(char **cmdline_p)
309{
310 enable_mmu();
311
312#ifdef CONFIG_CMDLINE_BOOL
313 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
314#endif
315
316 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
317
318#ifdef CONFIG_BLK_DEV_RAM
319 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
320 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
321 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
322#endif
323
324 if (!MOUNT_ROOT_RDONLY)
325 root_mountflags &= ~MS_RDONLY;
326 init_mm.start_code = (unsigned long) _text;
327 init_mm.end_code = (unsigned long) _etext;
328 init_mm.end_data = (unsigned long) _edata;
329 init_mm.brk = (unsigned long) _end;
330
331 code_resource.start = virt_to_phys(_text);
332 code_resource.end = virt_to_phys(_etext)-1;
333 data_resource.start = virt_to_phys(_etext);
334 data_resource.end = virt_to_phys(_edata)-1;
335
336 parse_early_param();
337
338 sh_mv_setup(cmdline_p);
339
340 /*
341 * Find the highest page frame number we have available
342 */
343 max_pfn = PFN_DOWN(__pa(memory_end));
344
345 /*
346 * Determine low and high memory ranges:
347 */
348 max_low_pfn = max_pfn;
349 min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
350
351 nodes_clear(node_online_map);
352 setup_memory();
353 paging_init();
354 sparse_init();
327 355
328#ifdef CONFIG_DUMMY_CONSOLE 356#ifdef CONFIG_DUMMY_CONSOLE
329 conswitchp = &dummy_con; 357 conswitchp = &dummy_con;
@@ -332,8 +360,6 @@ void __init setup_arch(char **cmdline_p)
332 /* Perform the machine specific initialisation */ 360 /* Perform the machine specific initialisation */
333 if (likely(sh_mv.mv_setup)) 361 if (likely(sh_mv.mv_setup))
334 sh_mv.mv_setup(cmdline_p); 362 sh_mv.mv_setup(cmdline_p);
335
336 paging_init();
337} 363}
338 364
339struct sh_machine_vector* __init get_mv_byname(const char* name) 365struct sh_machine_vector* __init get_mv_byname(const char* name)