Commit b9ba3a05 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] reorganise setup_arch() for ia32 discontigmem

This restructures setup_arch() for i386 to make it easier to include the
i386 numa changes (for CONFIG_DISCONTIGMEM) I've been working on.  It
also makes setup_arch() easier to read.  A version of this patch is the
in 2.4 aa tree.

This does not depend on the other patches I'm submitting today, but my
discontigmem patch does depend on this one.

I've tested this patch on the following configurations: UP, SMP, SMP
PAE, multiquad, multiquad PAE.
parent 2589a05f
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
#include <asm/setup.h>
/* /*
* Machine setup.. * Machine setup..
...@@ -599,72 +600,13 @@ static void __init parse_cmdline_early (char ** cmdline_p) ...@@ -599,72 +600,13 @@ static void __init parse_cmdline_early (char ** cmdline_p)
} }
} }
void __init setup_arch(char **cmdline_p)
{
unsigned long bootmap_size, low_mem_size;
unsigned long start_pfn, max_low_pfn;
int i;
early_cpu_init();
#ifdef CONFIG_VISWS
visws_get_board_type_and_rev();
#endif
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO;
screen_info = SCREEN_INFO;
apm_info.bios = APM_BIOS_INFO;
saved_videomode = VIDEO_MODE;
printk("Video mode to be used for restore is %lx\n", saved_videomode);
if( SYS_DESC_TABLE.length != 0 ) {
MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
machine_id = SYS_DESC_TABLE.table[0];
machine_submodel_id = SYS_DESC_TABLE.table[1];
BIOS_revision = SYS_DESC_TABLE.table[2];
}
aux_device_present = AUX_DEVICE_INFO;
#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
setup_memory_region();
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_cmdline_early(cmdline_p);
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
/* /*
* Reserved space for vmalloc and iomap - defined in asm/page.h * Find the highest page frame number we have available
*/ */
#define MAXMEM_PFN PFN_DOWN(MAXMEM) void __init find_max_pfn(void)
#define MAX_NONPAE_PFN (1 << 20) {
int i;
/*
* partially used pages are not usable - thus
* we are rounding upwards:
*/
start_pfn = PFN_UP(__pa(&_end));
/*
* Find the highest page frame number we have available
*/
max_pfn = 0; max_pfn = 0;
for (i = 0; i < e820.nr_map; i++) { for (i = 0; i < e820.nr_map; i++) {
unsigned long start, end; unsigned long start, end;
...@@ -678,10 +620,15 @@ void __init setup_arch(char **cmdline_p) ...@@ -678,10 +620,15 @@ void __init setup_arch(char **cmdline_p)
if (end > max_pfn) if (end > max_pfn)
max_pfn = end; max_pfn = end;
} }
}
/*
* Determine low and high memory ranges:
*/
unsigned long __init find_max_low_pfn(void)
{
unsigned long max_low_pfn;
/*
* Determine low and high memory ranges:
*/
max_low_pfn = max_pfn; max_low_pfn = max_pfn;
if (max_low_pfn > MAXMEM_PFN) { if (max_low_pfn > MAXMEM_PFN) {
if (highmem_pages == -1) if (highmem_pages == -1)
...@@ -731,28 +678,19 @@ void __init setup_arch(char **cmdline_p) ...@@ -731,28 +678,19 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n"); printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
#endif #endif
} }
return max_low_pfn;
}
#ifdef CONFIG_HIGHMEM /*
highstart_pfn = highend_pfn = max_pfn; * Register fully available low RAM pages with the bootmem allocator.
if (max_pfn > max_low_pfn) { */
highstart_pfn = max_low_pfn; static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
} {
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", int i;
pages_to_mb(highend_pfn - highstart_pfn));
#endif
printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
pages_to_mb(max_low_pfn));
/*
* Initialize the boot-time allocator (with low memory only):
*/
bootmap_size = init_bootmem(start_pfn, max_low_pfn);
/*
* Register fully available low RAM pages with the bootmem allocator.
*/
for (i = 0; i < e820.nr_map; i++) { for (i = 0; i < e820.nr_map; i++) {
unsigned long curr_pfn, last_pfn, size; unsigned long curr_pfn, last_pfn, size;
/* /*
* Reserve usable low memory * Reserve usable low memory
*/ */
if (e820.map[i].type != E820_RAM) if (e820.map[i].type != E820_RAM)
...@@ -781,6 +719,39 @@ void __init setup_arch(char **cmdline_p) ...@@ -781,6 +719,39 @@ void __init setup_arch(char **cmdline_p)
size = last_pfn - curr_pfn; size = last_pfn - curr_pfn;
free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
} }
}
static unsigned long __init setup_memory(void)
{
unsigned long bootmap_size, start_pfn, max_low_pfn;
/*
* partially used pages are not usable - thus
* we are rounding upwards:
*/
start_pfn = PFN_UP(__pa(&_end));
find_max_pfn();
max_low_pfn = find_max_low_pfn();
#ifdef CONFIG_HIGHMEM
highstart_pfn = highend_pfn = max_pfn;
if (max_pfn > max_low_pfn) {
highstart_pfn = max_low_pfn;
}
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
pages_to_mb(highend_pfn - highstart_pfn));
#endif
printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
pages_to_mb(max_low_pfn));
/*
* Initialize the boot-time allocator (with low memory only):
*/
bootmap_size = init_bootmem(start_pfn, max_low_pfn);
register_bootmem_low_pages(max_low_pfn);
/* /*
* Reserve the bootmem bitmap itself as well. We do this in two * Reserve the bootmem bitmap itself as well. We do this in two
* steps (first step was init_bootmem()) because this catches * steps (first step was init_bootmem()) because this catches
...@@ -816,6 +787,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -816,6 +787,7 @@ void __init setup_arch(char **cmdline_p)
*/ */
find_smp_config(); find_smp_config();
#endif #endif
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START) { if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
...@@ -833,33 +805,18 @@ void __init setup_arch(char **cmdline_p) ...@@ -833,33 +805,18 @@ void __init setup_arch(char **cmdline_p)
} }
} }
#endif #endif
return max_low_pfn;
}
/* /*
* NOTE: before this point _nobody_ is allowed to allocate * Request address space for all standard RAM and ROM resources
* any memory using the bootmem allocator. * and also for regions reported as reserved by the e820.
*/ */
static void __init register_memory(unsigned long max_low_pfn)
#ifdef CONFIG_SMP {
smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ unsigned long low_mem_size;
#endif int i;
paging_init();
#ifdef CONFIG_ACPI_BOOT
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
if (!acpi_disabled)
acpi_boot_init(*cmdline_p);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
if (smp_found_config)
get_smp_config();
#endif
/*
* Request address space for all standard RAM and ROM resources
* and also for regions reported as reserved by the e820.
*/
probe_roms(); probe_roms();
for (i = 0; i < e820.nr_map; i++) { for (i = 0; i < e820.nr_map; i++) {
struct resource *res; struct resource *res;
...@@ -896,6 +853,77 @@ void __init setup_arch(char **cmdline_p) ...@@ -896,6 +853,77 @@ void __init setup_arch(char **cmdline_p)
low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff; low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
if (low_mem_size > pci_mem_start) if (low_mem_size > pci_mem_start)
pci_mem_start = low_mem_size; pci_mem_start = low_mem_size;
}
void __init setup_arch(char **cmdline_p)
{
unsigned long max_low_pfn;
early_cpu_init();
#ifdef CONFIG_VISWS
visws_get_board_type_and_rev();
#endif
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO;
screen_info = SCREEN_INFO;
apm_info.bios = APM_BIOS_INFO;
saved_videomode = VIDEO_MODE;
printk("Video mode to be used for restore is %lx\n", saved_videomode);
if( SYS_DESC_TABLE.length != 0 ) {
MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
machine_id = SYS_DESC_TABLE.table[0];
machine_submodel_id = SYS_DESC_TABLE.table[1];
BIOS_revision = SYS_DESC_TABLE.table[2];
}
aux_device_present = AUX_DEVICE_INFO;
#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
setup_memory_region();
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_cmdline_early(cmdline_p);
max_low_pfn = setup_memory();
/*
* NOTE: before this point _nobody_ is allowed to allocate
* any memory using the bootmem allocator.
*/
#ifdef CONFIG_SMP
smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
#endif
paging_init();
#ifdef CONFIG_ACPI_BOOT
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
*/
if (!acpi_disabled)
acpi_boot_init(*cmdline_p);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
if (smp_found_config)
get_smp_config();
#endif
register_memory(max_low_pfn);
#ifdef CONFIG_VT #ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE) #if defined(CONFIG_VGA_CONSOLE)
......
...@@ -6,5 +6,14 @@ ...@@ -6,5 +6,14 @@
#ifndef _i386_SETUP_H #ifndef _i386_SETUP_H
#define _i386_SETUP_H #define _i386_SETUP_H
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
/*
* Reserved space for vmalloc and iomap - defined in asm/page.h
*/
#define MAXMEM_PFN PFN_DOWN(MAXMEM)
#define MAX_NONPAE_PFN (1 << 20)
#endif /* _i386_SETUP_H */ #endif /* _i386_SETUP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment