Skip to content

Commit

Permalink
sh: bootmem tidying for discontig/sparsemem preparation.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mundt authored and Paul Mundt committed May 7, 2007
1 parent 759ab06 commit 0106662
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 181 deletions.
164 changes: 95 additions & 69 deletions arch/sh/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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;

Expand Down Expand Up @@ -202,85 +205,45 @@ 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
* bootstrap step all allocations (until the page allocator
* 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
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions arch/sh/mm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,17 @@ config VSYSCALL
For systems with an MMU that can afford to give up a page,
(the default value) say Y.

config NODES_SHIFT
int
default "1"
depends on NEED_MULTIPLE_NODES

config ARCH_FLATMEM_ENABLE
def_bool y

config ARCH_POPULATES_NODE_MAP
def_bool y

choice
prompt "Kernel page size"
default PAGE_SIZE_4KB
Expand Down
Loading

0 comments on commit 0106662

Please sign in to comment.