]> git.hungrycats.org Git - linux/commitdiff
[PATCH] reorganise setup_arch() for ia32 discontigmem
authorAndrew Morton <akpm@zip.com.au>
Tue, 3 Sep 2002 12:33:56 +0000 (05:33 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 3 Sep 2002 12:33:56 +0000 (05:33 -0700)
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.

arch/i386/kernel/setup.c
include/asm-i386/setup.h

index 677fa295b4fe1e429c5eb487cbe17208fc4ea072..bcc3207ec4018718ac83d44bf9ed498a0601c5bb 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/highmem.h>
 #include <asm/e820.h>
 #include <asm/mpspec.h>
+#include <asm/setup.h>
 
 /*
  * Machine setup..
@@ -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)
-#define MAX_NONPAE_PFN (1 << 20)
-
-       /*
-        * partially used pages are not usable - thus
-        * we are rounding upwards:
-        */
-       start_pfn = PFN_UP(__pa(&_end));
+void __init find_max_pfn(void)
+{
+       int i;
 
-       /*
-        * Find the highest page frame number we have available
-        */
        max_pfn = 0;
        for (i = 0; i < e820.nr_map; i++) {
                unsigned long start, end;
@@ -678,10 +620,15 @@ void __init setup_arch(char **cmdline_p)
                if (end > max_pfn)
                        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;
        if (max_low_pfn > MAXMEM_PFN) {
                if (highmem_pages == -1)
@@ -731,28 +678,19 @@ void __init setup_arch(char **cmdline_p)
                        printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
 #endif
        }
+       return 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 fully available low RAM pages with the bootmem allocator.
+ */
+static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
+{
+       int i;
 
-       /*
-        * Register fully available low RAM pages with the bootmem allocator.
-        */
        for (i = 0; i < e820.nr_map; i++) {
                unsigned long curr_pfn, last_pfn, size;
-               /*
+               /*
                 * Reserve usable low memory
                 */
                if (e820.map[i].type != E820_RAM)
@@ -781,6 +719,39 @@ void __init setup_arch(char **cmdline_p)
                size = last_pfn - curr_pfn;
                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
         * steps (first step was init_bootmem()) because this catches
@@ -816,6 +787,7 @@ void __init setup_arch(char **cmdline_p)
         */
        find_smp_config();
 #endif
+
 #ifdef CONFIG_BLK_DEV_INITRD
        if (LOADER_TYPE && INITRD_START) {
                if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
@@ -833,33 +805,18 @@ void __init setup_arch(char **cmdline_p)
                }
        }
 #endif
+       return max_low_pfn;
+}
 
-       /*
-        * 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
-
+/*
+ * Request address space for all standard RAM and ROM resources
+ * and also for regions reported as reserved by the e820.
+ */
+static void __init register_memory(unsigned long max_low_pfn)
+{
+       unsigned long low_mem_size;
+       int i;
 
-       /*
-        * Request address space for all standard RAM and ROM resources
-        * and also for regions reported as reserved by the e820.
-        */
        probe_roms();
        for (i = 0; i < e820.nr_map; i++) {
                struct resource *res;
@@ -896,6 +853,77 @@ void __init setup_arch(char **cmdline_p)
        low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
        if (low_mem_size > pci_mem_start)
                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
 #if defined(CONFIG_VGA_CONSOLE)
index ae25cc4275d36899fcba33c0cf8ff824c873f809..19df0edea3b23da5fc06a5cf4706fec36924be12 100644 (file)
@@ -6,5 +6,14 @@
 #ifndef _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 */