diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-03-28 16:38:13 +0900 |
---|---|---|
committer | Paul Mundt <lethal@hera.kernel.org> | 2007-05-07 02:10:54 +0000 |
commit | 01066625e9ae39742c92e21163f7f2a818e02762 (patch) | |
tree | c5b8a2a2c9de29ed13094891fce2b7f5769ffca7 /arch/sh/kernel | |
parent | 759ab068c4d4216c4ad247bfa851601dfb6500dc (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')
-rw-r--r-- | arch/sh/kernel/setup.c | 164 |
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 @@ * This file handles the architecture-dependent parts of initialization * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt */ #include <linux/screen_info.h> #include <linux/ioport.h> @@ -15,15 +15,18 @@ #include <linux/seq_file.h> #include <linux/root_dev.h> #include <linux/utsname.h> +#include <linux/nodemask.h> #include <linux/cpu.h> #include <linux/pfn.h> #include <linux/fs.h> +#include <linux/mm.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/sections.h> #include <asm/irq.h> #include <asm/setup.h> #include <asm/clock.h> +#include <asm/mmu_context.h> extern void * __rd_start, * __rd_end; @@ -202,53 +205,33 @@ static int __init sh_mv_setup(char **cmdline_p) return 0; } -void __init setup_arch(char **cmdline_p) +/* + * Register fully available low RAM pages with the bootmem allocator. + */ +static void __init register_bootmem_low_pages(void) { - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, max_low_pfn; - -#ifdef CONFIG_CMDLINE_BOOL - strcpy(COMMAND_LINE, CONFIG_CMDLINE); -#endif - - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); - -#ifdef CONFIG_BLK_DEV_RAM - rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; - rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); - rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); -#endif - - if (!MOUNT_ROOT_RDONLY) - root_mountflags &= ~MS_RDONLY; - init_mm.start_code = (unsigned long) _text; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; - - code_resource.start = (unsigned long)virt_to_phys(_text); - code_resource.end = (unsigned long)virt_to_phys(_etext)-1; - data_resource.start = (unsigned long)virt_to_phys(_etext); - data_resource.end = (unsigned long)virt_to_phys(_edata)-1; - - sh_mv_setup(cmdline_p); - + unsigned long curr_pfn, last_pfn, pages; /* - * Find the highest page frame number we have available + * We are rounding up the start address of usable memory: */ - max_pfn = PFN_DOWN(__pa(memory_end)); + curr_pfn = PFN_UP(__MEMORY_START); /* - * Determine low and high memory ranges: + * ... and at the end of the usable range downwards: */ - max_low_pfn = max_pfn; + last_pfn = PFN_DOWN(__pa(memory_end)); - /* - * Partially used pages are not usable - thus - * we are rounding upwards: - */ - start_pfn = PFN_UP(__pa(_end)); + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + pages = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); +} + +void __init setup_bootmem_allocator(unsigned long start_pfn) +{ + unsigned long bootmap_size; /* * Find a proper area for the bootmem bitmap. After this @@ -256,31 +239,11 @@ void __init setup_arch(char **cmdline_p) * is intact) must be done via bootmem_alloc(). */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, - __MEMORY_START>>PAGE_SHIFT, - max_low_pfn); - /* - * Register fully available low RAM pages with the bootmem allocator. - */ - { - unsigned long curr_pfn, last_pfn, pages; - - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(__MEMORY_START); - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(__pa(memory_end)); + min_low_pfn, max_low_pfn); - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - pages = last_pfn - curr_pfn; - free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn), - PFN_PHYS(pages)); - } + register_bootmem_low_pages(); + node_set_online(0); /* * Reserve the kernel text and @@ -289,14 +252,14 @@ void __init setup_arch(char **cmdline_p) * case of us accidentally initializing the bootmem allocator with * an invalid RAM area. */ - reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE, + reserve_bootmem(__MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); /* * reserve physical page 0 - it's a special BIOS page on many boxes, * enabling clean reboots, SMP operation, laptop functions. */ - reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); + reserve_bootmem(__MEMORY_START, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); @@ -310,8 +273,8 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem_node(NODE_DATA(0), INITRD_START + - __MEMORY_START, INITRD_SIZE); + reserve_bootmem(INITRD_START + __MEMORY_START, + INITRD_SIZE); initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; @@ -324,6 +287,71 @@ void __init setup_arch(char **cmdline_p) } } #endif +} + +#ifndef CONFIG_NEED_MULTIPLE_NODES +static void __init setup_memory(void) +{ + unsigned long start_pfn; + + /* + * Partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(_end)); + setup_bootmem_allocator(start_pfn); +} +#else +extern void __init setup_memory(void); +#endif + +void __init setup_arch(char **cmdline_p) +{ + enable_mmu(); + +#ifdef CONFIG_CMDLINE_BOOL + strcpy(COMMAND_LINE, CONFIG_CMDLINE); +#endif + + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); + +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif + + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + init_mm.start_code = (unsigned long) _text; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = (unsigned long) _end; + + code_resource.start = virt_to_phys(_text); + code_resource.end = virt_to_phys(_etext)-1; + data_resource.start = virt_to_phys(_etext); + data_resource.end = virt_to_phys(_edata)-1; + + parse_early_param(); + + sh_mv_setup(cmdline_p); + + /* + * Find the highest page frame number we have available + */ + max_pfn = PFN_DOWN(__pa(memory_end)); + + /* + * Determine low and high memory ranges: + */ + max_low_pfn = max_pfn; + min_low_pfn = __MEMORY_START >> PAGE_SHIFT; + + nodes_clear(node_online_map); + setup_memory(); + paging_init(); + sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -332,8 +360,6 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); - - paging_init(); } struct sh_machine_vector* __init get_mv_byname(const char* name) |