From 0dbfafa5fcd4dd189e2adc7b6ed9e0405e846d79 Mon Sep 17 00:00:00 2001 From: Alexander van Heukelum Date: Wed, 23 Apr 2008 15:09:05 +0200 Subject: x86: move i386 memory setup code to e820_32.c The x86_64 code has centralized the memory setup code in e820_64.c. This patch copies that approach to i386: - early_param("mem", ...) parsing is moved from setup_32.c to e820_32.c. - setup_memory_map() and finish_e820_parsing() are factored out from setup_arch(), and declarations are added to e820_32.h. - print_memory_map() is made static and removed from e820_32.h. - user_defined_memmap is marked as __initdata. Signed-off-by: Alexander van Heukelum Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 50 ++-------------------------------------------- 1 file changed, 2 insertions(+), 48 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 2c5f8b213e86..b54c79c91efd 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -237,42 +237,6 @@ static inline void copy_edd(void) } #endif -int __initdata user_defined_memmap; - -/* - * "mem=nopentium" disables the 4MB page tables. - * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM - * to , overriding the bios size. - * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from - * to +, overriding the bios size. - * - * HPA tells me bootloaders need to parse mem=, so no new - * option should be mem= [also see Documentation/i386/boot.txt] - */ -static int __init parse_mem(char *arg) -{ - if (!arg) - return -EINVAL; - - if (strcmp(arg, "nopentium") == 0) { - setup_clear_cpu_cap(X86_FEATURE_PSE); - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. - */ - unsigned long long mem_size; - - mem_size = memparse(arg, &arg); - limit_regions(mem_size); - user_defined_memmap = 1; - } - return 0; -} -early_param("mem", parse_mem); - #ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header * stored by the crashed kernel. @@ -725,12 +689,6 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif -/* Overridden in paravirt.c if CONFIG_PARAVIRT */ -char * __init __attribute__((weak)) memory_setup(void) -{ - return machine_specific_memory_setup(); -} - #ifdef CONFIG_NUMA /* * In the golden day, when everything among i386 and x86_64 will be @@ -786,8 +744,7 @@ void __init setup_arch(char **cmdline_p) #endif ARCH_SETUP - printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - print_memory_map(memory_setup()); + setup_memory_map(); copy_edd(); @@ -807,10 +764,7 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); - if (user_defined_memmap) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - print_memory_map("user"); - } + finish_e820_parsing(); strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; -- cgit v1.2.3 From b79cd8f1268bab57ff85b19d131f7f23deab2dee Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 11 May 2008 00:30:15 -0700 Subject: x86: make e820.c to have common functions remove the duplicated copy of these functions. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index b54c79c91efd..5faeab69edd9 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -875,7 +875,7 @@ void __init setup_arch(char **cmdline_p) get_smp_config(); #endif - e820_register_memory(); + e820_setup_gap(); e820_mark_nosave_regions(); #ifdef CONFIG_VT -- cgit v1.2.3 From a4c81cf684350797939416c99effb9d3ae46bca6 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 18 May 2008 01:18:57 -0700 Subject: x86: extend e820 ealy_res support 32bit move early_res related from e820_64.c to e820.c make edba detection to be done in head32.c remove smp_alloc_memory, because we have fixed trampoline address now. Signed-off-by: Yinghai Lu arch/x86/kernel/e820.c | 214 ++++++++++++++++++++++++++++++++++++ arch/x86/kernel/e820_64.c | 196 -------------------------------- arch/x86/kernel/head32.c | 76 ++++++++++++ arch/x86/kernel/setup_32.c | 109 +++--------------- arch/x86/kernel/smpboot.c | 17 -- arch/x86/kernel/trampoline.c | 2 arch/x86/mach-voyager/voyager_smp.c | 9 - include/asm-x86/e820.h | 6 + include/asm-x86/e820_64.h | 9 - include/asm-x86/smp.h | 1 arch/x86/kernel/e820.c | 214 ++++++++++++++++++++++++++++++++++++ arch/x86/kernel/e820_64.c | 196 -------------------------------- arch/x86/kernel/head32.c | 76 ++++++++++++ arch/x86/kernel/setup_32.c | 109 +++--------------- arch/x86/kernel/smpboot.c | 17 -- arch/x86/kernel/trampoline.c | 2 arch/x86/mach-voyager/voyager_smp.c | 9 - include/asm-x86/e820.h | 6 + include/asm-x86/e820_64.h | 9 - include/asm-x86/smp.h | 1 arch/x86/kernel/e820.c | 214 ++++++++++++++++++++++++++++++++++++ arch/x86/kernel/e820_64.c | 196 -------------------------------- arch/x86/kernel/head32.c | 76 ++++++++++++ arch/x86/kernel/setup_32.c | 109 +++--------------- arch/x86/kernel/smpboot.c | 17 -- arch/x86/kernel/trampoline.c | 2 arch/x86/mach-voyager/voyager_smp.c | 9 - include/asm-x86/e820.h | 6 + include/asm-x86/e820_64.h | 9 - include/asm-x86/smp.h | 1 10 files changed, 320 insertions(+), 319 deletions(-) Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 109 ++++++++++----------------------------------- 1 file changed, 23 insertions(+), 86 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5faeab69edd9..fed482c62450 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -359,56 +359,6 @@ unsigned long __init find_max_low_pfn(void) return max_low_pfn; } -#define BIOS_LOWMEM_KILOBYTES 0x413 - -/* - * The BIOS places the EBDA/XBDA at the top of conventional - * memory, and usually decreases the reported amount of - * conventional memory (int 0x12) too. This also contains a - * workaround for Dell systems that neglect to reserve EBDA. - * The same workaround also avoids a problem with the AMD768MPX - * chipset: reserve a page before VGA to prevent PCI prefetch - * into it (errata #56). Usually the page is reserved anyways, - * unless you have no PS/2 mouse plugged in. - */ -static void __init reserve_ebda_region(void) -{ - unsigned int lowmem, ebda_addr; - - /* To determine the position of the EBDA and the */ - /* end of conventional memory, we need to look at */ - /* the BIOS data area. In a paravirtual environment */ - /* that area is absent. We'll just have to assume */ - /* that the paravirt case can handle memory setup */ - /* correctly, without our help. */ - if (paravirt_enabled()) - return; - - /* end of low (conventional) memory */ - lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); - lowmem <<= 10; - - /* start of EBDA area */ - ebda_addr = get_bios_ebda(); - - /* Fixup: bios puts an EBDA in the top 64K segment */ - /* of conventional memory, but does not adjust lowmem. */ - if ((lowmem - ebda_addr) <= 0x10000) - lowmem = ebda_addr; - - /* Fixup: bios does not report an EBDA at all. */ - /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ - if ((ebda_addr == 0) && (lowmem >= 0x9f000)) - lowmem = 0x9f000; - - /* Paranoia: should never happen, but... */ - if ((lowmem == 0) || (lowmem >= 0x100000)) - lowmem = 0x9f000; - - /* reserve all memory between lowmem and the 1MB mark */ - reserve_bootmem(lowmem, 0x100000 - lowmem, BOOTMEM_DEFAULT); -} - #ifndef CONFIG_NEED_MULTIPLE_NODES static void __init setup_bootmem_allocator(void); static unsigned long __init setup_memory(void) @@ -522,25 +472,32 @@ static void __init reserve_initrd(void) unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; unsigned long ramdisk_here; - initrd_start = 0; - if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) return; /* No initrd provided by bootloader */ + initrd_start = 0; + if (ramdisk_end < ramdisk_image) { + free_bootmem(ramdisk_image, ramdisk_size); printk(KERN_ERR "initrd wraps around end of memory, " "disabling initrd\n"); return; } if (ramdisk_size >= end_of_lowmem/2) { + free_bootmem(ramdisk_image, ramdisk_size); printk(KERN_ERR "initrd too large to handle, " "disabling initrd\n"); return; } + if (ramdisk_end <= end_of_lowmem) { /* All in lowmem, easy case */ - reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT); + /* + * don't need to reserve again, already reserved early + * in i386_start_kernel, and early_res_to_bootmem + * convert that to reserved in bootmem + */ initrd_start = ramdisk_image + PAGE_OFFSET; initrd_end = initrd_start+ramdisk_size; return; @@ -582,6 +539,8 @@ static void __init relocate_initrd(void) p = (char *)__va(ramdisk_image); memcpy(q, p, clen); q += clen; + /* need to free these low pages...*/ + free_bootmem(ramdisk_image, clen); ramdisk_image += clen; ramdisk_size -= clen; } @@ -600,47 +559,28 @@ static void __init relocate_initrd(void) ramdisk_image += clen; ramdisk_size -= clen; } + /* high pages is not converted by early_res_to_bootmem */ } #endif /* CONFIG_BLK_DEV_INITRD */ void __init setup_bootmem_allocator(void) { - unsigned long bootmap_size; + unsigned long bootmap_size, bootmap; /* * Initialize the boot-time allocator (with low memory only): */ - bootmap_size = init_bootmem(min_low_pfn, max_low_pfn); - + bootmap_size = bootmem_bootmap_pages(max_low_pfn)<> PAGE_SHIFT, max_low_pfn); register_bootmem_low_pages(max_low_pfn); + early_res_to_bootmem(0, max_low_pfn< Date: Wed, 21 May 2008 18:40:18 -0700 Subject: x86: extend e820 ealy_res support 32bit - fix use find_e820_area to find addess for new RAMDISK, instead of using ram blindly also print out low ram and bootmap info Signed-off-by: Yinghai Lu Cc: Andrew Morton Cc: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 55 ++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index fed482c62450..3c451d143eba 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -466,11 +466,11 @@ static bool do_relocate_initrd = false; static void __init reserve_initrd(void) { - unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; - unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; - unsigned long ramdisk_end = ramdisk_image + ramdisk_size; - unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; - unsigned long ramdisk_here; + u64 ramdisk_image = boot_params.hdr.ramdisk_image; + u64 ramdisk_size = boot_params.hdr.ramdisk_size; + u64 ramdisk_end = ramdisk_image + ramdisk_size; + u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; + u64 ramdisk_here; if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) @@ -478,14 +478,8 @@ static void __init reserve_initrd(void) initrd_start = 0; - if (ramdisk_end < ramdisk_image) { - free_bootmem(ramdisk_image, ramdisk_size); - printk(KERN_ERR "initrd wraps around end of memory, " - "disabling initrd\n"); - return; - } if (ramdisk_size >= end_of_lowmem/2) { - free_bootmem(ramdisk_image, ramdisk_size); + free_early(ramdisk_image, ramdisk_image + ramdisk_size - 1); printk(KERN_ERR "initrd too large to handle, " "disabling initrd\n"); return; @@ -495,8 +489,7 @@ static void __init reserve_initrd(void) /* All in lowmem, easy case */ /* * don't need to reserve again, already reserved early - * in i386_start_kernel, and early_res_to_bootmem - * convert that to reserved in bootmem + * in i386_start_kernel */ initrd_start = ramdisk_image + PAGE_OFFSET; initrd_end = initrd_start+ramdisk_size; @@ -504,11 +497,14 @@ static void __init reserve_initrd(void) } /* We need to move the initrd down into lowmem */ - ramdisk_here = (end_of_lowmem - ramdisk_size) & PAGE_MASK; + ramdisk_here = find_e820_area(min_low_pfn<> PAGE_SHIFT, max_low_pfn); + printk(KERN_INFO " low ram: %08lx - %08lx\n", + min_low_pfn< Date: Tue, 20 May 2008 20:10:58 -0700 Subject: x86: move e820_mark_nosave_regions to e820.c and make e820_mark_nosave_regions to take limit_pfn to use max_low_pfn for 32bit and end_pfn for 64bit Signed-off-by: Yinghai Lu Cc: Andrew Morton Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 3c451d143eba..e1173aecf69a 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -820,7 +820,7 @@ void __init setup_arch(char **cmdline_p) #endif e820_setup_gap(); - e820_mark_nosave_regions(); + e820_mark_nosave_regions(max_low_pfn); #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) -- cgit v1.2.3 From 136ef671df04dc157afa0d4b96c7bd23ba072c9c Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Tue, 20 May 2008 00:29:59 +0400 Subject: x86: allow MPPARSE to be deselected in SMP configs --- arch/x86/kernel/setup_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index e1173aecf69a..c04e8c91daf7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -814,7 +814,7 @@ void __init setup_arch(char **cmdline_p) "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); #endif #endif -#ifdef CONFIG_X86_LOCAL_APIC +#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) if (smp_found_config) get_smp_config(); #endif -- cgit v1.2.3 From 3945e2c9abf8e00c2edc4aa29215ddfad1cd8cf7 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 25 May 2008 10:00:09 -0700 Subject: x86: extend e820 ealy_res support 32bit - fix #2 remove extra -1 in reseve_early calling panic if can not find space for new RAMDISK Signed-off-by: Yinghai Lu Cc: Andrew Morton Cc: Jeremy Fitzhardinge Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index c04e8c91daf7..08b47a2f7af0 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -479,7 +479,7 @@ static void __init reserve_initrd(void) initrd_start = 0; if (ramdisk_size >= end_of_lowmem/2) { - free_early(ramdisk_image, ramdisk_image + ramdisk_size - 1); + free_early(ramdisk_image, ramdisk_end); printk(KERN_ERR "initrd too large to handle, " "disabling initrd\n"); return; @@ -501,9 +501,13 @@ static void __init reserve_initrd(void) end_of_lowmem, ramdisk_size, PAGE_SIZE); + if (ramdisk_here == -1ULL) + panic("Cannot find place for new RAMDISK of size %lld\n", + ramdisk_size); + /* Note: this includes all the lowmem currently occupied by the initrd, we rely on that fact to keep the data intact. */ - reserve_early(ramdisk_here, ramdisk_here + ramdisk_size - 1, + reserve_early(ramdisk_here, ramdisk_here + ramdisk_size, "NEW RAMDISK"); initrd_start = ramdisk_here + PAGE_OFFSET; initrd_end = initrd_start + ramdisk_size; @@ -579,15 +583,15 @@ void __init setup_bootmem_allocator(void) PAGE_SIZE); if (bootmap == -1L) panic("Cannot find bootmem map of size %ld\n", bootmap_size); - reserve_early(bootmap, bootmap + bootmap_size - 1, "BOOTMAP"); + reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP"); #ifdef CONFIG_BLK_DEV_INITRD reserve_initrd(); #endif bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, max_low_pfn); printk(KERN_INFO " low ram: %08lx - %08lx\n", min_low_pfn< Date: Thu, 29 May 2008 12:56:36 -0700 Subject: x86: extend e820 early_res support 32bit -fix #3 introduce init_pg_table_start, so xen PV could specify the value. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 08b47a2f7af0..de9c5ee77d07 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -71,6 +71,7 @@ /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* address, and must not be in the .bss segment! */ +unsigned long init_pg_tables_start __initdata = ~0UL; unsigned long init_pg_tables_end __initdata = ~0UL; /* @@ -485,6 +486,10 @@ static void __init reserve_initrd(void) return; } + printk(KERN_INFO "old RAMDISK: %08llx - %08llx\n", ramdisk_image, + ramdisk_end); + + if (ramdisk_end <= end_of_lowmem) { /* All in lowmem, easy case */ /* @@ -511,6 +516,8 @@ static void __init reserve_initrd(void) "NEW RAMDISK"); initrd_start = ramdisk_here + PAGE_OFFSET; initrd_end = initrd_start + ramdisk_size; + printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", + ramdisk_here, ramdisk_here + ramdisk_size); do_relocate_initrd = true; } -- cgit v1.2.3 From a5481280b29b6a3db912ec100498bd31eaa6d2db Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 29 May 2008 12:58:37 -0700 Subject: x86: extend e820 early_res support 32bit -fix #5 reserve early numa kva, so it will not clash with new RAMDISK Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index de9c5ee77d07..6f40cb560ea9 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -614,7 +614,6 @@ void __init setup_bootmem_allocator(void) */ find_smp_config(); #endif - numa_kva_reserve(); reserve_crashkernel(); reserve_ibft_region(); -- cgit v1.2.3 From 0596152388e234efebce464355186ad9e16c8cb6 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 31 May 2008 22:52:47 -0700 Subject: x86, 32-bit: change propagate_e820_map() back to find_max_pfn() we don't need to call memory_present that early. numa and sparse will call memory_present later and might even fail, it will call memory_present for the full range. also for sparse it will call alloc_bootmem ... before we set up bootmem. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 6f40cb560ea9..29010420458d 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -730,10 +730,10 @@ void __init setup_arch(char **cmdline_p) efi_init(); /* update e820 for memory not covered by WB MTRRs */ - propagate_e820_map(); + find_max_pfn(); mtrr_bp_init(); if (mtrr_trim_uncached_memory(max_pfn)) - propagate_e820_map(); + find_max_pfn(); max_low_pfn = setup_memory(); -- cgit v1.2.3 From 6af61a7614a306fe882a0c2b4ddc63b65aa66efc Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 1 Jun 2008 23:53:50 -0700 Subject: x86: clean up max_pfn_mapped usage - 32-bit on 32-bit in head_32.S after initial page table is done, we get initial max_pfn_mapped, and then kernel_physical_mapping_init will give us a final one. We need to use that to make sure find_e820_area will get valid addresses for boot_map and for NODE_DATA(0) on numa32. XEN PV and lguest may need to assign max_pfn_mapped too. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 29010420458d..c985a8c305e0 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -586,7 +586,7 @@ void __init setup_bootmem_allocator(void) */ bootmap_size = bootmem_bootmap_pages(max_low_pfn)<> PAGE_SHIFT, max_low_pfn); + printk(KERN_INFO " mapped low ram: 0 - %08lx\n", + max_pfn_mapped< Date: Tue, 3 Jun 2008 10:24:49 -0700 Subject: x86: change propagate_e820_map() back to find_max_pfn(), 32-bit, fix add memory_present() calls for sparse and non-numa. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index c985a8c305e0..ccf3595202fa 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -377,11 +377,13 @@ static unsigned long __init setup_memory(void) if (max_pfn > max_low_pfn) { highstart_pfn = max_low_pfn; } + memory_present(0, 0, highend_pfn); printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); num_physpages = highend_pfn; high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; #else + memory_present(0, 0, max_low_pfn); num_physpages = max_low_pfn; high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; #endif -- cgit v1.2.3 From 7b2a0a6c4866cac146dcb0433e6984eb19a81335 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 3 Jun 2008 19:35:04 -0700 Subject: x86: make 32-bit use e820_register_active_regions() this way 32-bit is more similar to 64-bit, and smarter e820 and numa. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index ccf3595202fa..0ec6480aaa27 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -405,11 +405,12 @@ static void __init zone_sizes_init(void) max_zone_pfns[ZONE_DMA] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + remove_all_active_ranges(); #ifdef CONFIG_HIGHMEM max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; - add_active_range(0, 0, highend_pfn); + e820_register_active_regions(0, 0, highend_pfn); #else - add_active_range(0, 0, max_low_pfn); + e820_register_active_regions(0, 0, max_low_pfn); #endif free_area_init_nodes(max_zone_pfns); @@ -582,6 +583,7 @@ static void __init relocate_initrd(void) void __init setup_bootmem_allocator(void) { + int i; unsigned long bootmap_size, bootmap; /* * Initialize the boot-time allocator (with low memory only): @@ -603,7 +605,8 @@ void __init setup_bootmem_allocator(void) min_low_pfn< Date: Mon, 2 Jun 2008 14:26:21 +0800 Subject: x86: reserve EFI memory map with reserve_early This patch reserves the EFI memory map with reserve_early(). Because EFI memory map is allocated by bootloader, if it is not reserved by reserved_early(), it may be overwritten through address returned by find_e820_area(). Signed-off-by: Huang Ying Cc: andi@firstfloor.org Cc: mingo@redhat.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 0ec6480aaa27..2960cbecfa5a 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -67,6 +67,7 @@ #include #include #include +#include /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* @@ -683,8 +684,10 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_EFI if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, - "EL32", 4)) + "EL32", 4)) { efi_enabled = 1; + efi_reserve_early(); + } #endif ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); -- cgit v1.2.3 From c45a707dbe35cb9aa6490223e5b1129fa3583948 Mon Sep 17 00:00:00 2001 From: "Huang, Ying" Date: Mon, 2 Jun 2008 14:26:25 +0800 Subject: x86: linked list of setup_data for i386 This patch adds linked list of struct setup_data supported for i386. Signed-off-by: Huang Ying Cc: andi@firstfloor.org Cc: mingo@redhat.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 2960cbecfa5a..ee1ccdbd7100 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -681,6 +681,7 @@ void __init setup_arch(char **cmdline_p) pre_setup_arch_hook(); early_cpu_init(); early_ioremap_init(); + reserve_setup_data(); #ifdef CONFIG_EFI if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, @@ -729,6 +730,8 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(&__bss_start); bss_resource.end = virt_to_phys(&__bss_stop)-1; + parse_setup_data(); + parse_early_param(); finish_e820_parsing(); -- cgit v1.2.3 From e0da33646826b66ef933d47ea2fb7a693fd849bf Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 8 Jun 2008 18:29:22 -0700 Subject: x86: introduce max_physical_apicid for bigsmp switching a multi-socket test-system with 3 or 4 ioapics, when 4 dualcore cpus or 2 quadcore cpus installed, needs to switch to bigsmp or physflat. CPU apic id is [4,11] instead of [0,7], and we need to check max apic id instead of cpu numbers. also add check for 32 bit when acpi is not compiled in or acpi=off. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index ee1ccdbd7100..be1a99003677 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -838,18 +838,17 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_ACPI acpi_boot_init(); - +#endif +#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) + if (smp_found_config) + get_smp_config(); +#endif #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) if (def_to_bigsmp) printk(KERN_WARNING "More than 8 CPUs detected and " "CONFIG_X86_PC cannot handle it.\nUse " "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); #endif -#endif -#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) - if (smp_found_config) - get_smp_config(); -#endif e820_setup_gap(); e820_mark_nosave_regions(max_low_pfn); -- cgit v1.2.3 From 6780711e9817585f89b02b0556aac3564cbe1f45 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 8 Jun 2008 19:53:26 -0700 Subject: x86: update mptable, fix need to call early_reserve_e820() to preallocate mptable for 32bit Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index be1a99003677..4fa9f6c4542b 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -749,6 +749,8 @@ void __init setup_arch(char **cmdline_p) */ max_pfn = e820_end_of_ram(); + /* preallocate 4k for mptable mpc */ + early_reserve_e820_mpc_new(); /* update e820 for memory not covered by WB MTRRs */ mtrr_bp_init(); if (mtrr_trim_uncached_memory(max_pfn)) { -- cgit v1.2.3 From 9a27f5c51629c3d3b7718dd4be3d2722b472fafe Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 13 Jun 2008 20:07:03 -0700 Subject: x86: clean up relocate_initrd 1. move that before zone_sizes_init ... 2. add free_early for one old one, otherwise it will be be reserved again when we init highmem. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 1d4be07e15e5..72b11d4557b7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -584,6 +584,9 @@ static void __init relocate_initrd(void) printk(KERN_INFO "Copied RAMDISK from %016llx - %016llx to %08llx - %08llx\n", ramdisk_image, ramdisk_image + ramdisk_size - 1, ramdisk_here, ramdisk_here + ramdisk_size - 1); + + /* need to free that, otherwise init highmem will reserve it again */ + free_early(ramdisk_image, ramdisk_image+ramdisk_size); } #endif /* CONFIG_BLK_DEV_INITRD */ @@ -801,10 +804,6 @@ void __init setup_arch(char **cmdline_p) init_ohci1394_dma_on_all_controllers(); #endif - remapped_pgdat_init(); - sparse_init(); - zone_sizes_init(); - /* * NOTE: at this point the bootmem allocator is fully available. */ @@ -813,6 +812,10 @@ void __init setup_arch(char **cmdline_p) relocate_initrd(); #endif + remapped_pgdat_init(); + sparse_init(); + zone_sizes_init(); + paravirt_post_allocator_init(); dmi_scan_machine(); -- cgit v1.2.3 From 41c094fd3ca54f1a71233049cf136ff94c91f4ae Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 16 Jun 2008 13:03:31 -0700 Subject: x86: move e820_resource_resources to e820.c and make 32-bit resource registration more like 64 bit. also move probe_roms back to setup_32.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 208 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 175 insertions(+), 33 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 72b11d4557b7..f3ddba5ed9a7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -445,25 +445,28 @@ static void __init reserve_crashkernel(void) ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base); if (ret == 0 && crash_size > 0) { - if (crash_base > 0) { - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(total_mem >> 20)); - - if (reserve_bootmem(crash_base, crash_size, - BOOTMEM_EXCLUSIVE) < 0) { - printk(KERN_INFO "crashkernel reservation " - "failed - memory is in use\n"); - return; - } - - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - } else + if (crash_base <= 0) { printk(KERN_INFO "crashkernel reservation failed - " "you have to specify a base address\n"); + return; + } + + if (reserve_bootmem_generic(crash_base, crash_size, + BOOTMEM_EXCLUSIVE) < 0) { + printk(KERN_INFO "crashkernel reservation failed - " + "memory is in use\n"); + return; + } + + printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " + "for crashkernel (System RAM: %ldMB)\n", + (unsigned long)(crash_size >> 20), + (unsigned long)(crash_base >> 20), + (unsigned long)(total_mem >> 20)); + + crashk_res.start = crash_base; + crashk_res.end = crash_base + crash_size - 1; + insert_resource(&iomem_resource, &crashk_res); } } #else @@ -675,6 +678,8 @@ int x86_cpu_to_node_map_init[NR_CPUS] = { DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; #endif +static void probe_roms(void); + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -684,6 +689,7 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; */ void __init setup_arch(char **cmdline_p) { + int i; unsigned long max_low_pfn; memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); @@ -745,6 +751,13 @@ void __init setup_arch(char **cmdline_p) finish_e820_parsing(); + probe_roms(); + + /* after parse_early_param, so could debug it */ + insert_resource(&iomem_resource, &code_resource); + insert_resource(&iomem_resource, &data_resource); + insert_resource(&iomem_resource, &bss_resource); + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; @@ -861,9 +874,16 @@ void __init setup_arch(char **cmdline_p) "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); #endif - e820_setup_gap(); + e820_reserve_resources(); e820_mark_nosave_regions(max_low_pfn); + request_resource(&iomem_resource, &video_ram_resource); + /* request I/O space for devices used on all i[345]86 PCs */ + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + request_resource(&ioport_resource, &standard_io_resources[i]); + + e820_setup_gap(); + #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) @@ -874,25 +894,147 @@ void __init setup_arch(char **cmdline_p) #endif } -/* - * Request address space for all standard resources - * - * This is called just before pcibios_init(), which is also a - * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). - */ -static int __init request_standard_resources(void) +static struct resource system_rom_resource = { + .name = "System ROM", + .start = 0xf0000, + .end = 0xfffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource extension_rom_resource = { + .name = "Extension ROM", + .start = 0xe0000, + .end = 0xeffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource adapter_rom_resources[] = { { + .name = "Adapter ROM", + .start = 0xc8000, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +} }; + +static struct resource video_rom_resource = { + .name = "Video ROM", + .start = 0xc0000, + .end = 0xc7fff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +#define ROMSIGNATURE 0xaa55 + +static int __init romsignature(const unsigned char *rom) +{ + const unsigned short * const ptr = (const unsigned short *)rom; + unsigned short sig; + + return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; +} + +static int __init romchecksum(const unsigned char *rom, unsigned long length) +{ + unsigned char sum, c; + + for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) + sum += c; + return !length && !sum; +} + +static void __init probe_roms(void) { + const unsigned char *rom; + unsigned long start, length, upper; + unsigned char c; int i; - printk(KERN_INFO "Setting up standard PCI resources\n"); - init_iomem_resources(&code_resource, &data_resource, &bss_resource); + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; - request_resource(&iomem_resource, &video_ram_resource); + video_rom_resource.start = start; - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); - return 0; + if (probe_kernel_address(rom + 2, c) != 0) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = c * 512; + + /* if checksum okay, trust length byte */ + if (length && romchecksum(rom, length)) + video_rom_resource.end = start + length - 1; + + request_resource(&iomem_resource, &video_rom_resource); + break; + } + + start = (video_rom_resource.end + 1 + 2047) & ~2047UL; + if (start < upper) + start = upper; + + /* system rom */ + request_resource(&iomem_resource, &system_rom_resource); + upper = system_rom_resource.start; + + /* check for extension rom (ignore length byte!) */ + rom = isa_bus_to_virt(extension_rom_resource.start); + if (romsignature(rom)) { + length = extension_rom_resource.end - extension_rom_resource.start + 1; + if (romchecksum(rom, length)) { + request_resource(&iomem_resource, &extension_rom_resource); + upper = extension_rom_resource.start; + } + } + + /* check for adapter roms on 2k boundaries */ + for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + if (probe_kernel_address(rom + 2, c) != 0) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = c * 512; + + /* but accept any length that fits if checksum okay */ + if (!length || start + length > upper || !romchecksum(rom, length)) + continue; + + adapter_rom_resources[i].start = start; + adapter_rom_resources[i].end = start + length - 1; + request_resource(&iomem_resource, &adapter_rom_resources[i]); + + start = adapter_rom_resources[i++].end & ~2047UL; + } } -subsys_initcall(request_standard_resources); -- cgit v1.2.3 From cc9f7a0ccf000d4db5fbdc7b0ae48eefea102f69 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 16 Jun 2008 16:11:08 -0700 Subject: x86: kill bad_ppro so don't punish all other cpus without that problem when init highmem Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index f3ddba5ed9a7..9692aeb8ecae 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -68,6 +68,7 @@ #include #include #include +#include /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* @@ -764,6 +765,14 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_init(); + if (ppro_with_ram_bug()) { + e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM, + E820_RESERVED); + sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); + printk(KERN_INFO "fixed physical RAM map:\n"); + e820_print_map("bad_ppro"); + } + e820_register_active_regions(0, 0, -1UL); /* * partially used pages are not usable - thus -- cgit v1.2.3 From 593a0cc39046515a438ca9fcc168115961f9f503 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 17 Jun 2008 10:02:45 -0700 Subject: x86: move some function out of setup_bootmem_alloc ... to make it more like 64-bit. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 9692aeb8ecae..90a2b857b4a7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -623,21 +623,6 @@ void __init setup_bootmem_allocator(void) free_bootmem_with_active_regions(i, max_low_pfn); early_res_to_bootmem(0, max_low_pfn< Date: Tue, 17 Jun 2008 15:41:45 -0700 Subject: x86: use acpi_numa_init to parse on 32-bit numa seperate SRAT finding and parsing from get_memcfg_from_srat, and let getmemcfg_from_srat only handle array from previous step. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 90a2b857b4a7..7e06ecd83174 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -184,6 +185,12 @@ int bootloader_type; /* user-defined highmem size */ static unsigned int highmem_pages = -1; +/* + * Early DMI memory + */ +int dmi_alloc_index; +char dmi_alloc_data[DMI_MAX_DATA]; + /* * Setup options */ @@ -775,6 +782,24 @@ void __init setup_arch(char **cmdline_p) max_pfn = e820_end_of_ram(); } + dmi_scan_machine(); + + io_delay_init(); + +#ifdef CONFIG_ACPI + /* + * Parse the ACPI tables for possible boot-time SMP configuration. + */ + acpi_boot_table_init(); +#endif + +#ifdef CONFIG_ACPI_NUMA + /* + * Parse SRAT to discover nodes. + */ + acpi_numa_init(); +#endif + max_low_pfn = setup_memory(); #ifdef CONFIG_ACPI_SLEEP @@ -841,10 +866,6 @@ void __init setup_arch(char **cmdline_p) paravirt_post_allocator_init(); - dmi_scan_machine(); - - io_delay_init(); - #ifdef CONFIG_X86_SMP /* * setup to use the early static init tables during kernel startup @@ -861,13 +882,6 @@ void __init setup_arch(char **cmdline_p) generic_apic_probe(); #endif -#ifdef CONFIG_ACPI - /* - * Parse the ACPI tables for possible boot-time SMP configuration. - */ - acpi_boot_table_init(); -#endif - early_quirks(); #ifdef CONFIG_ACPI -- cgit v1.2.3 From 23ca4bba3e20c6c3cb11c1bb0ab4770b724d39ac Mon Sep 17 00:00:00 2001 From: Mike Travis Date: Mon, 12 May 2008 21:21:12 +0200 Subject: x86: cleanup early per cpu variables/accesses v4 * Introduce a new PER_CPU macro called "EARLY_PER_CPU". This is used by some per_cpu variables that are initialized and accessed before there are per_cpu areas allocated. ["Early" in respect to per_cpu variables is "earlier than the per_cpu areas have been setup".] This patchset adds these new macros: DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) EXPORT_EARLY_PER_CPU_SYMBOL(_name) DECLARE_EARLY_PER_CPU(_type, _name) early_per_cpu_ptr(_name) early_per_cpu_map(_name, _idx) early_per_cpu(_name, _cpu) The DEFINE macro defines the per_cpu variable as well as the early map and pointer. It also initializes the per_cpu variable and map elements to "_initvalue". The early_* macros provide access to the initial map (usually setup during system init) and the early pointer. This pointer is initialized to point to the early map but is then NULL'ed when the actual per_cpu areas are setup. After that the per_cpu variable is the correct access to the variable. The early_per_cpu() macro is not very efficient but does show how to access the variable if you have a function that can be called both "early" and "late". It tests the early ptr to be NULL, and if not then it's still valid. Otherwise, the per_cpu variable is used instead: #define early_per_cpu(_name, _cpu) \ (early_per_cpu_ptr(_name) ? \ early_per_cpu_ptr(_name)[_cpu] : \ per_cpu(_name, _cpu)) A better method is to actually check the pointer manually. In the case below, numa_set_node can be called both "early" and "late": void __cpuinit numa_set_node(int cpu, int node) { int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map); if (cpu_to_node_map) cpu_to_node_map[cpu] = node; else per_cpu(x86_cpu_to_node_map, cpu) = node; } * Add a flag "arch_provides_topology_pointers" that indicates pointers to topology cpumask_t maps are available. Otherwise, use the function returning the cpumask_t value. This is useful if cpumask_t set size is very large to avoid copying data on to/off of the stack. * The coverage of CONFIG_DEBUG_PER_CPU_MAPS has been increased while the non-debug case has been optimized a bit. * Remove an unreferenced compiler warning in drivers/base/topology.c * Clean up #ifdef in setup.c For inclusion into sched-devel/latest tree. Based on: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git + sched-devel/latest .../mingo/linux-2.6-sched-devel.git Signed-off-by: Mike Travis Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- arch/x86/kernel/setup_32.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5a2f8e063887..ccd5f5cdbbe6 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -737,18 +737,6 @@ char * __init __attribute__((weak)) memory_setup(void) return machine_specific_memory_setup(); } -#ifdef CONFIG_NUMA -/* - * In the golden day, when everything among i386 and x86_64 will be - * integrated, this will not live here - */ -void *x86_cpu_to_node_map_early_ptr; -int x86_cpu_to_node_map_init[NR_CPUS] = { - [0 ... NR_CPUS-1] = NUMA_NO_NODE -}; -DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; -#endif - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -887,18 +875,6 @@ void __init setup_arch(char **cmdline_p) io_delay_init(); -#ifdef CONFIG_X86_SMP - /* - * setup to use the early static init tables during kernel startup - * X86_SMP will exclude sub-arches that don't deal well with it. - */ - x86_cpu_to_apicid_early_ptr = (void *)x86_cpu_to_apicid_init; - x86_bios_cpu_apicid_early_ptr = (void *)x86_bios_cpu_apicid_init; -#ifdef CONFIG_NUMA - x86_cpu_to_node_map_early_ptr = (void *)x86_cpu_to_node_map_init; -#endif -#endif - #ifdef CONFIG_X86_GENERICARCH generic_apic_probe(); #endif -- cgit v1.2.3 From 1ecd27657b735128a728ebf0c31fce5e1456718a Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Fri, 20 Jun 2008 15:38:22 +0200 Subject: x86: unify crashkernel reservation for 32 and 64 bit This patch moves the reserve_crashkernel() to setup.c and removes the architecture-specific version. Both versions were more or less the same. I tested it on both x86-64 and i386, with CONFIG_KEXEC on and off (so that it compiles). Signed-off-by: Bernhard Walle Cc: yhlu.kernel@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 53 ---------------------------------------------- 1 file changed, 53 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index a9b19ad24edb..369d0fe1ff9c 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -429,59 +429,6 @@ extern unsigned long __init setup_memory(void); extern void zone_sizes_init(void); #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -static inline unsigned long long get_total_mem(void) -{ - unsigned long long total; - - total = max_low_pfn - min_low_pfn; -#ifdef CONFIG_HIGHMEM - total += highend_pfn - highstart_pfn; -#endif - - return total << PAGE_SHIFT; -} - -#ifdef CONFIG_KEXEC -static void __init reserve_crashkernel(void) -{ - unsigned long long total_mem; - unsigned long long crash_size, crash_base; - int ret; - - total_mem = get_total_mem(); - - ret = parse_crashkernel(boot_command_line, total_mem, - &crash_size, &crash_base); - if (ret == 0 && crash_size > 0) { - if (crash_base <= 0) { - printk(KERN_INFO "crashkernel reservation failed - " - "you have to specify a base address\n"); - return; - } - - if (reserve_bootmem_generic(crash_base, crash_size, - BOOTMEM_EXCLUSIVE) < 0) { - printk(KERN_INFO "crashkernel reservation failed - " - "memory is in use\n"); - return; - } - - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(total_mem >> 20)); - - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - insert_resource(&iomem_resource, &crashk_res); - } -} -#else -static inline void __init reserve_crashkernel(void) -{} -#endif - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; -- cgit v1.2.3 From 3c999f142665265afd0fe9190204dd051f17e505 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 20 Jun 2008 16:11:20 -0700 Subject: x86: check command line when CONFIG_X86_MPPARSE is not set, v2 if acpi=off, acpi=noirq and pci=noacpi, we need to disable apic. Signed-off-by: Yinghai Lu Cc: Andrew Morton Cc: "Maciej W. Rozycki" Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 369d0fe1ff9c..cad4e893df05 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -677,6 +677,11 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + if (acpi_mps_check()){ + enable_local_apic = -1; + clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); + } + finish_e820_parsing(); probe_roms(); -- cgit v1.2.3 From 04606618bb50c4ec754585a82732ea4facfe2bc9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 01:38:41 -0700 Subject: x86: remove some acpi ifdefs in setup_32/64 Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index cad4e893df05..e274ee6ff582 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -726,12 +726,10 @@ void __init setup_arch(char **cmdline_p) io_delay_init(); -#ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. */ acpi_boot_table_init(); -#endif #ifdef CONFIG_ACPI_NUMA /* @@ -812,9 +810,8 @@ void __init setup_arch(char **cmdline_p) early_quirks(); -#ifdef CONFIG_ACPI acpi_boot_init(); -#endif + #if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) if (smp_found_config) get_smp_config(); -- cgit v1.2.3 From a9c1182fbd349882fe912245d6e03cd30943be2d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 15:39:41 -0700 Subject: x86: seperate probe_roms into another file it is only needed for 32bit Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 146 --------------------------------------------- 1 file changed, 146 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index e274ee6ff582..865838b11792 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -606,8 +606,6 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif -static void probe_roms(void); - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -843,147 +841,3 @@ void __init setup_arch(char **cmdline_p) #endif } -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -#define ROMSIGNATURE 0xaa55 - -static int __init romsignature(const unsigned char *rom) -{ - const unsigned short * const ptr = (const unsigned short *)rom; - unsigned short sig; - - return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; -} - -static int __init romchecksum(const unsigned char *rom, unsigned long length) -{ - unsigned char sum, c; - - for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) - sum += c; - return !length && !sum; -} - -static void __init probe_roms(void) -{ - const unsigned char *rom; - unsigned long start, length, upper; - unsigned char c; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - if (probe_kernel_address(rom + 2, c) != 0) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = c * 512; - - /* if checksum okay, trust length byte */ - if (length && romchecksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (romchecksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - if (probe_kernel_address(rom + 2, c) != 0) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = c * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !romchecksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -- cgit v1.2.3 From f81be876eaa9c71b3024c3dc05e4d1bf210cc255 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 19:16:52 -0700 Subject: x86: remove two duplicated funcs in setup_32.c early_cpu_init is declared in processor.h memory_setup is defined in e820.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 865838b11792..602a45c59ff6 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -206,7 +206,6 @@ struct ist_info ist_info; EXPORT_SYMBOL(ist_info); #endif -extern void early_cpu_init(void); extern int root_mountflags; unsigned long saved_video_mode; -- cgit v1.2.3 From ce97c40e28223c148e142bda7af48fd0f27c81f9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 20:22:09 -0700 Subject: x86: move reserve_standard_io_resource to setup.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 57 +--------------------------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 602a45c59ff6..2574ec8234c7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -108,58 +108,6 @@ static struct resource video_ram_resource = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer0", - .start = 0x0040, - .end = 0x0043, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer1", - .start = 0x0050, - .end = 0x0053, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x0060, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0064, - .end = 0x0064, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; /* common cpu data for all cpus */ @@ -614,7 +562,6 @@ static void set_mca_bus(int x) { } */ void __init setup_arch(char **cmdline_p) { - int i; unsigned long max_low_pfn; memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); @@ -824,9 +771,7 @@ void __init setup_arch(char **cmdline_p) e820_mark_nosave_regions(max_low_pfn); request_resource(&iomem_resource, &video_ram_resource); - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); + reserve_standard_io_resources(); e820_setup_gap(); -- cgit v1.2.3 From 17b4cceb1feb2a8865ce47064dd3bd446063a5d5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Jun 2008 21:02:20 -0700 Subject: x86: move elfcorehdr parsing to setup.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 2574ec8234c7..d24ac268523f 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -194,21 +193,6 @@ static inline void copy_edd(void) } #endif -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. - */ -static int __init parse_elfcorehdr(char *arg) -{ - if (!arg) - return -EINVAL; - - elfcorehdr_addr = memparse(arg, &arg); - return 0; -} -early_param("elfcorehdr", parse_elfcorehdr); -#endif /* CONFIG_PROC_VMCORE */ - /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. -- cgit v1.2.3 From b2ac82a0909aea0d2620ba4c189f37c567c21fe5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 22 Jun 2008 02:45:39 -0700 Subject: x86: introduce initmem_init for 32 bit Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 94 +--------------------------------------------- 1 file changed, 2 insertions(+), 92 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index d24ac268523f..190546bd3bd3 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -300,71 +300,11 @@ unsigned long __init find_max_low_pfn(void) return max_low_pfn; } -#ifndef CONFIG_NEED_MULTIPLE_NODES -static void __init setup_bootmem_allocator(void); -static unsigned long __init setup_memory(void) -{ - /* - * partially used pages are not usable - thus - * we are rounding upwards: - */ - min_low_pfn = PFN_UP(init_pg_tables_end); - - 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; - } - memory_present(0, 0, highend_pfn); - printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", - pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - memory_present(0, 0, max_low_pfn); - num_physpages = max_low_pfn; - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; -#endif -#ifdef CONFIG_FLATMEM - max_mapnr = num_physpages; -#endif - printk(KERN_NOTICE "%ldMB LOWMEM available.\n", - pages_to_mb(max_low_pfn)); - - setup_bootmem_allocator(); - - return max_low_pfn; -} - -static void __init zone_sizes_init(void) -{ - unsigned long max_zone_pfns[MAX_NR_ZONES]; - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - remove_all_active_ranges(); -#ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; - e820_register_active_regions(0, 0, highend_pfn); -#else - e820_register_active_regions(0, 0, max_low_pfn); -#endif - - free_area_init_nodes(max_zone_pfns); -} -#else -extern unsigned long __init setup_memory(void); -extern void zone_sizes_init(void); -#endif /* !CONFIG_NEED_MULTIPLE_NODES */ - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; -static void __init reserve_initrd(void) +void __init reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -480,36 +420,6 @@ static void __init relocate_initrd(void) #endif /* CONFIG_BLK_DEV_INITRD */ -void __init setup_bootmem_allocator(void) -{ - int i; - unsigned long bootmap_size, bootmap; - /* - * Initialize the boot-time allocator (with low memory only): - */ - bootmap_size = bootmem_bootmap_pages(max_low_pfn)<> PAGE_SHIFT, max_low_pfn); - printk(KERN_INFO " mapped low ram: 0 - %08lx\n", - max_pfn_mapped<0 pgdats have their virtual @@ -666,7 +576,7 @@ void __init setup_arch(char **cmdline_p) acpi_numa_init(); #endif - max_low_pfn = setup_memory(); + max_low_pfn = initmem_init(0, max_pfn); #ifdef CONFIG_ACPI_SLEEP /* -- cgit v1.2.3 From 225c37d71bc8b97eb2063e8eda153b383328b20b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 22 Jun 2008 02:46:58 -0700 Subject: x86: introduce reserve_initrd Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 190546bd3bd3..90b51047ce63 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -336,7 +336,7 @@ void __init reserve_initrd(void) * in i386_start_kernel */ initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start+ramdisk_size; + initrd_end = initrd_start + ramdisk_size; return; } @@ -363,7 +363,7 @@ void __init reserve_initrd(void) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) -static void __init relocate_initrd(void) +static void __init post_reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -417,7 +417,13 @@ static void __init relocate_initrd(void) /* need to free that, otherwise init highmem will reserve it again */ free_early(ramdisk_image, ramdisk_image+ramdisk_size); } - +#else +void __init reserve_initrd(void) +{ +} +static void __init post_reserve_initrd(void) +{ +} #endif /* CONFIG_BLK_DEV_INITRD */ /* @@ -632,9 +638,7 @@ void __init setup_arch(char **cmdline_p) * NOTE: at this point the bootmem allocator is fully available. */ -#ifdef CONFIG_BLK_DEV_INITRD - relocate_initrd(); -#endif + post_reserve_initrd(); remapped_pgdat_init(); sparse_init(); -- cgit v1.2.3 From 7f0be02c5ed1deb04c54c6a17f412e04f417df11 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 22 Jun 2008 17:37:54 -0700 Subject: x86: move boot_params declaring to setup.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 90b51047ce63..3149f434d7d0 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -163,12 +163,6 @@ unsigned long saved_video_mode; static char __initdata command_line[COMMAND_LINE_SIZE]; -#ifndef CONFIG_DEBUG_BOOT_PARAMS -struct boot_params __initdata boot_params; -#else -struct boot_params boot_params; -#endif - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE -- cgit v1.2.3 From 90d967e0ef68f5312ed4b081d5c9312ff53c1c93 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 21:00:45 +0200 Subject: x86: move find_max_low_pfn to init_32.c Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 77 ---------------------------------------------- 1 file changed, 77 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 3149f434d7d0..13155009ce94 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -129,9 +129,6 @@ unsigned int BIOS_revision; /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; -/* user-defined highmem size */ -static unsigned int highmem_pages = -1; - /* * Early DMI memory */ @@ -187,21 +184,6 @@ static inline void copy_edd(void) } #endif -/* - * highmem=size forces highmem to be exactly 'size' bytes. - * This works even on boxes that have no highmem otherwise. - * This also works to reduce highmem size on bigger boxes. - */ -static int __init parse_highmem(char *arg) -{ - if (!arg) - return -EINVAL; - - highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; - return 0; -} -early_param("highmem", parse_highmem); - /* * vmalloc=size forces the vmalloc area to be exactly 'size' * bytes. This can be used to increase (or decrease) the @@ -235,65 +217,6 @@ static int __init parse_reservetop(char *arg) } early_param("reservetop", parse_reservetop); -/* - * Determine low and high memory ranges: - */ -unsigned long __init find_max_low_pfn(void) -{ - unsigned long max_low_pfn; - - max_low_pfn = max_pfn; - if (max_low_pfn > MAXMEM_PFN) { - if (highmem_pages == -1) - highmem_pages = max_pfn - MAXMEM_PFN; - if (highmem_pages + MAXMEM_PFN < max_pfn) - max_pfn = MAXMEM_PFN + highmem_pages; - if (highmem_pages + MAXMEM_PFN > max_pfn) { - printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages)); - highmem_pages = 0; - } - max_low_pfn = MAXMEM_PFN; -#ifndef CONFIG_HIGHMEM - /* Maximum memory usable is what is directly addressable */ - printk(KERN_WARNING "Warning only %ldMB will be used.\n", - MAXMEM>>20); - if (max_pfn > MAX_NONPAE_PFN) - printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n"); - else - printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); - max_pfn = MAXMEM_PFN; -#else /* !CONFIG_HIGHMEM */ -#ifndef CONFIG_HIGHMEM64G - if (max_pfn > MAX_NONPAE_PFN) { - max_pfn = MAX_NONPAE_PFN; - printk(KERN_WARNING "Warning only 4GB will be used.\n"); - printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n"); - } -#endif /* !CONFIG_HIGHMEM64G */ -#endif /* !CONFIG_HIGHMEM */ - } else { - if (highmem_pages == -1) - highmem_pages = 0; -#ifdef CONFIG_HIGHMEM - if (highmem_pages >= max_pfn) { - printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn)); - highmem_pages = 0; - } - if (highmem_pages) { - if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){ - printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages)); - highmem_pages = 0; - } - max_low_pfn -= highmem_pages; - } -#else - if (highmem_pages) - printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n"); -#endif - } - return max_low_pfn; -} - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; -- cgit v1.2.3 From bef1568d9714f1162086c32583ba7984a7ca8e3e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 22 Jun 2008 17:40:10 -0700 Subject: x86: move reservetop and vmalloc parsing to pgtable_32.c also change reserve_top_address to __init attibute Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 13155009ce94..9a08490a3889 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -184,39 +184,6 @@ static inline void copy_edd(void) } #endif -/* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; - - __VMALLOC_RESERVE = memparse(arg, &arg); - return 0; -} -early_param("vmalloc", parse_vmalloc); - -/* - * reservetop=size reserves a hole at the top of the kernel address space which - * a hypervisor can load into later. Needed for dynamically loaded hypervisors, - * so relocating the fixmap can be done before paging initialization. - */ -static int __init parse_reservetop(char *arg) -{ - unsigned long address; - - if (!arg) - return -EINVAL; - - address = memparse(arg, &arg); - reserve_top_address(address); - return 0; -} -early_param("reservetop", parse_reservetop); - #ifdef CONFIG_BLK_DEV_INITRD static bool do_relocate_initrd = false; -- cgit v1.2.3 From 2ec65f8b89ea003c27ff7723525a2ee335a2b393 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 03:05:30 -0700 Subject: x86: clean up using max_low_pfn on 32-bit so that max_low_pfn is not changed after it is set. so we can move that early and out of initmem_init. could call find_low_pfn_range just after max_pfn is set. also could move reserve_initrd out of setup_bootmem_allocator so 32bit is more like 64bit. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 9a08490a3889..b42f570a5a56 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -188,13 +188,14 @@ static inline void copy_edd(void) static bool do_relocate_initrd = false; -void __init reserve_initrd(void) +static void __init reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; u64 ramdisk_here; + u64 ramdisk_target; if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) @@ -202,7 +203,7 @@ void __init reserve_initrd(void) initrd_start = 0; - if (ramdisk_size >= end_of_lowmem/2) { + if (ramdisk_size >= (end_of_lowmem>>1)) { free_early(ramdisk_image, ramdisk_end); printk(KERN_ERR "initrd too large to handle, " "disabling initrd\n"); @@ -225,7 +226,8 @@ void __init reserve_initrd(void) } /* We need to move the initrd down into lowmem */ - ramdisk_here = find_e820_area(min_low_pfn<>1), end_of_lowmem, ramdisk_size, PAGE_SIZE); @@ -346,8 +348,6 @@ static void set_mca_bus(int x) { } */ void __init setup_arch(char **cmdline_p) { - unsigned long max_low_pfn; - memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); pre_setup_arch_hook(); early_cpu_init(); @@ -450,6 +450,10 @@ void __init setup_arch(char **cmdline_p) max_pfn = e820_end_of_ram(); } + find_low_pfn_range(); + + reserve_initrd(); + dmi_scan_machine(); io_delay_init(); @@ -466,7 +470,7 @@ void __init setup_arch(char **cmdline_p) acpi_numa_init(); #endif - max_low_pfn = initmem_init(0, max_pfn); + initmem_init(0, max_pfn); #ifdef CONFIG_ACPI_SLEEP /* -- cgit v1.2.3 From 3eb11edc1321e14a121deeb8b18c177750226eca Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Jun 2008 22:19:22 +0200 Subject: x86: build fix fix: arch/x86/kernel/setup_32.c:409: error: 'enable_local_apic' undeclared (first use in this function) arch/x86/kernel/setup_32.c:409: error: (Each undeclared identifier is reported only once arch/x86/kernel/setup_32.c:409: error: for each function it appears in.) Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index b42f570a5a56..1e670372c191 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -406,7 +406,9 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); if (acpi_mps_check()){ +#ifdef CONFIG_X86_LOCAL_APIC enable_local_apic = -1; +#endif clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC); } -- cgit v1.2.3 From 11cd0bc140b5d66566c9eb49c1058737888cd75c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 19:51:10 -0700 Subject: x86: move some func calling from setup_arch to paging_init those function depend on paging setup pgtable, so they could access the ram in bootmem region but just get mapped. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 1e670372c191..220d92faf0a9 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -249,7 +249,7 @@ static void __init reserve_initrd(void) #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) -static void __init post_reserve_initrd(void) +void __init post_reserve_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -307,29 +307,11 @@ static void __init post_reserve_initrd(void) void __init reserve_initrd(void) { } -static void __init post_reserve_initrd(void) +void __init post_reserve_initrd(void) { } #endif /* CONFIG_BLK_DEV_INITRD */ -/* - * The node 0 pgdat is initialized before all of these because - * it's needed for bootmem. node>0 pgdats have their virtual - * space allocated before the pagetables are in place to access - * them, so they can't be cleared then. - * - * This should all compile down to nothing when NUMA is off. - */ -static void __init remapped_pgdat_init(void) -{ - int nid; - - for_each_online_node(nid) { - if (nid != 0) - memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); - } -} - #ifdef CONFIG_MCA static void set_mca_bus(int x) { @@ -524,18 +506,6 @@ void __init setup_arch(char **cmdline_p) init_ohci1394_dma_on_all_controllers(); #endif - /* - * NOTE: at this point the bootmem allocator is fully available. - */ - - post_reserve_initrd(); - - remapped_pgdat_init(); - sparse_init(); - zone_sizes_init(); - - paravirt_post_allocator_init(); - #ifdef CONFIG_X86_GENERICARCH generic_apic_probe(); #endif -- cgit v1.2.3 From 7465252ea0121c9cd28be68dfb86293a7554a111 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 19:53:33 -0700 Subject: x86: setup_arch 32bit move efi check later Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 220d92faf0a9..52f4e01bb655 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -336,14 +336,6 @@ void __init setup_arch(char **cmdline_p) early_ioremap_init(); reserve_setup_data(); -#ifdef CONFIG_EFI - if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, - "EL32", 4)) { - efi_enabled = 1; - efi_reserve_early(); - } -#endif - ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); screen_info = boot_params.screen_info; edid_info = boot_params.edid_info; @@ -363,10 +355,17 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((boot_params.hdr.ram_size & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((boot_params.hdr.ram_size & RAMDISK_LOAD_FLAG) != 0); #endif +#ifdef CONFIG_EFI + if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, + "EL32", 4)) { + efi_enabled = 1; + efi_reserve_early(); + } +#endif + ARCH_SETUP setup_memory_map(); - copy_edd(); if (!boot_params.hdr.root_flags) -- cgit v1.2.3 From 9a2e59302668b9ac2fb2a2c9bca1fc793c5d0409 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 19:54:23 -0700 Subject: x86: setup_arch 32bit move command line copying early Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 52f4e01bb655..243b2f7ca137 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -382,6 +382,9 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(&__bss_start); bss_resource.end = virt_to_phys(&__bss_stop)-1; + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + *cmdline_p = command_line; + parse_setup_data(); parse_early_param(); @@ -402,9 +405,6 @@ void __init setup_arch(char **cmdline_p) insert_resource(&iomem_resource, &data_resource); insert_resource(&iomem_resource, &bss_resource); - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - if (efi_enabled) efi_init(); -- cgit v1.2.3 From 295deae401fc5b6f215e876d93b40f25cb968c88 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 23 Jun 2008 19:55:05 -0700 Subject: x86: setup_arch 32bit move kvm_guest_init later Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 243b2f7ca137..bba8d57bd7d8 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -482,8 +482,6 @@ void __init setup_arch(char **cmdline_p) */ vmi_init(); #endif - kvm_guest_init(); - /* * NOTE: before this point _nobody_ is allowed to allocate * any memory using the bootmem allocator. Although the @@ -511,9 +509,15 @@ void __init setup_arch(char **cmdline_p) early_quirks(); + /* + * Read APIC and some other early information from ACPI tables. + */ acpi_boot_init(); #if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS) + /* + * get boot-time SMP configuration: + */ if (smp_found_config) get_smp_config(); #endif @@ -523,6 +527,7 @@ void __init setup_arch(char **cmdline_p) "CONFIG_X86_PC cannot handle it.\nUse " "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); #endif + kvm_guest_init(); e820_reserve_resources(); e820_mark_nosave_regions(max_low_pfn); -- cgit v1.2.3 From 4e29684c40f2a332ba4d05f6482d5807725d5624 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 24 Jun 2008 12:18:14 -0700 Subject: x86: introduce init_memory_mapping for 32bit #1 ... so can we use mem below max_low_pfn earlier. this allows us to move several functions more early instead of waiting to after paging_init. That includes moving relocate_initrd() earlier in the bootup, and kva related early setup done in initmem_init. (in followup patches) Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index bba8d57bd7d8..03007cada0d1 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -226,10 +226,8 @@ static void __init reserve_initrd(void) } /* We need to move the initrd down into lowmem */ - ramdisk_target = max_pfn_mapped<>1), - end_of_lowmem, ramdisk_size, - PAGE_SIZE); + ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, + PAGE_SIZE); if (ramdisk_here == -1ULL) panic("Cannot find place for new RAMDISK of size %lld\n", @@ -433,8 +431,12 @@ void __init setup_arch(char **cmdline_p) max_pfn = e820_end_of_ram(); } + /* max_low_pfn get updated here */ find_low_pfn_range(); + /* max_pfn_mapped is updated here */ + init_memory_mapping(0, (max_low_pfn << PAGE_SHIFT)); + reserve_initrd(); dmi_scan_machine(); -- cgit v1.2.3 From cfb0e53b05402f1ce65053677409a819c1798d34 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 24 Jun 2008 12:18:58 -0700 Subject: x86: introduce init_memory_mapping for 32bit #2 moving relocate_initrd early Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 03007cada0d1..4b953dc93883 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -186,7 +186,7 @@ static inline void copy_edd(void) #ifdef CONFIG_BLK_DEV_INITRD -static bool do_relocate_initrd = false; +static void __init relocate_initrd(void); static void __init reserve_initrd(void) { @@ -195,7 +195,6 @@ static void __init reserve_initrd(void) u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; u64 ramdisk_here; - u64 ramdisk_target; if (!boot_params.hdr.type_of_loader || !ramdisk_image || !ramdisk_size) @@ -242,12 +241,12 @@ static void __init reserve_initrd(void) printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", ramdisk_here, ramdisk_here + ramdisk_size); - do_relocate_initrd = true; + relocate_initrd(); } #define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) -void __init post_reserve_initrd(void) +static void __init relocate_initrd(void) { u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; @@ -256,9 +255,6 @@ void __init post_reserve_initrd(void) unsigned long slop, clen, mapaddr; char *p, *q; - if (!do_relocate_initrd) - return; - ramdisk_here = initrd_start - PAGE_OFFSET; q = (char *)initrd_start; @@ -269,10 +265,6 @@ void __init post_reserve_initrd(void) p = (char *)__va(ramdisk_image); memcpy(q, p, clen); q += clen; - /* need to free these low pages...*/ - printk(KERN_INFO "Freeing old partial RAMDISK %08llx-%08llx\n", - ramdisk_image, ramdisk_image + clen - 1); - free_bootmem(ramdisk_image, clen); ramdisk_image += clen; ramdisk_size -= clen; } @@ -298,16 +290,16 @@ void __init post_reserve_initrd(void) ramdisk_image, ramdisk_image + ramdisk_size - 1, ramdisk_here, ramdisk_here + ramdisk_size - 1); - /* need to free that, otherwise init highmem will reserve it again */ + /* + * need to free old one, otherwise init cross max_low_pfn could be + * converted to bootmem + */ free_early(ramdisk_image, ramdisk_image+ramdisk_size); } #else void __init reserve_initrd(void) { } -void __init post_reserve_initrd(void) -{ -} #endif /* CONFIG_BLK_DEV_INITRD */ #ifdef CONFIG_MCA -- cgit v1.2.3 From b9d19f4a51447930db002409945ad40a7a373cb0 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 26 Jun 2008 00:44:56 -0700 Subject: x86: fix memory setup bug interesting... [ 0.000000] mapped low ram: 0 - 20000000 [ 0.000000] low ram: 00000000 - 1fff0000 [ 0.000000] bootmap 00002000 - 00006000 max_pfn_mapped > max_low_pfn? it seems init_memory_mapping reveals an old bug. please check attached test patch. Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 4b953dc93883..392812d3c63c 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -427,7 +427,7 @@ void __init setup_arch(char **cmdline_p) find_low_pfn_range(); /* max_pfn_mapped is updated here */ - init_memory_mapping(0, (max_low_pfn << PAGE_SHIFT)); + max_pfn_mapped = init_memory_mapping(0, (max_low_pfn << PAGE_SHIFT)); reserve_initrd(); -- cgit v1.2.3 From 08afc7c0dd8ecb04c7a6fe367102e410a74abbe6 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Jun 2008 17:48:23 -0700 Subject: x86: we can use full bootmem after have init_memory_mapping So remove outdated comments Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 392812d3c63c..5e919e2b99fc 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -476,15 +476,6 @@ void __init setup_arch(char **cmdline_p) */ vmi_init(); #endif - /* - * NOTE: before this point _nobody_ is allowed to allocate - * any memory using the bootmem allocator. Although the - * allocator is now initialised only the first 8Mb of the kernel - * virtual address space has been mapped. All allocations before - * paging_init() has completed must use the alloc_bootmem_low_pages() - * variant (which allocates DMA'able memory) and care must be taken - * not to exceed the 8Mb limit. - */ paging_init(); -- cgit v1.2.3 From eb1379cb296f5aee348c2e04317d911bb84d9184 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Jun 2008 17:49:26 -0700 Subject: x86: update reserve_initrd to support 64bit Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 109 +++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 54 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5e919e2b99fc..aa81779db218 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -186,43 +186,18 @@ static inline void copy_edd(void) #ifdef CONFIG_BLK_DEV_INITRD -static void __init relocate_initrd(void); +#ifdef CONFIG_X86_32 -static void __init reserve_initrd(void) +#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) +static void __init relocate_initrd(void) { + u64 ramdisk_image = boot_params.hdr.ramdisk_image; u64 ramdisk_size = boot_params.hdr.ramdisk_size; - u64 ramdisk_end = ramdisk_image + ramdisk_size; u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; u64 ramdisk_here; - - if (!boot_params.hdr.type_of_loader || - !ramdisk_image || !ramdisk_size) - return; /* No initrd provided by bootloader */ - - initrd_start = 0; - - if (ramdisk_size >= (end_of_lowmem>>1)) { - free_early(ramdisk_image, ramdisk_end); - printk(KERN_ERR "initrd too large to handle, " - "disabling initrd\n"); - return; - } - - printk(KERN_INFO "old RAMDISK: %08llx - %08llx\n", ramdisk_image, - ramdisk_end); - - - if (ramdisk_end <= end_of_lowmem) { - /* All in lowmem, easy case */ - /* - * don't need to reserve again, already reserved early - * in i386_start_kernel - */ - initrd_start = ramdisk_image + PAGE_OFFSET; - initrd_end = initrd_start + ramdisk_size; - return; - } + unsigned long slop, clen, mapaddr; + char *p, *q; /* We need to move the initrd down into lowmem */ ramdisk_here = find_e820_area(0, end_of_lowmem, ramdisk_size, @@ -241,22 +216,6 @@ static void __init reserve_initrd(void) printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", ramdisk_here, ramdisk_here + ramdisk_size); - relocate_initrd(); -} - -#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT) - -static void __init relocate_initrd(void) -{ - u64 ramdisk_image = boot_params.hdr.ramdisk_image; - u64 ramdisk_size = boot_params.hdr.ramdisk_size; - u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; - u64 ramdisk_here; - unsigned long slop, clen, mapaddr; - char *p, *q; - - ramdisk_here = initrd_start - PAGE_OFFSET; - q = (char *)initrd_start; /* Copy any lowmem portion of the initrd */ @@ -286,18 +245,60 @@ static void __init relocate_initrd(void) /* high pages is not converted by early_res_to_bootmem */ ramdisk_image = boot_params.hdr.ramdisk_image; ramdisk_size = boot_params.hdr.ramdisk_size; - printk(KERN_INFO "Copied RAMDISK from %016llx - %016llx to %08llx - %08llx\n", + printk(KERN_INFO "Move RAMDISK from %016llx - %016llx to" + " %08llx - %08llx\n", ramdisk_image, ramdisk_image + ramdisk_size - 1, ramdisk_here, ramdisk_here + ramdisk_size - 1); +} +#endif - /* - * need to free old one, otherwise init cross max_low_pfn could be - * converted to bootmem - */ - free_early(ramdisk_image, ramdisk_image+ramdisk_size); +static void __init reserve_initrd(void) +{ + u64 ramdisk_image = boot_params.hdr.ramdisk_image; + u64 ramdisk_size = boot_params.hdr.ramdisk_size; + u64 ramdisk_end = ramdisk_image + ramdisk_size; + u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT; + + if (!boot_params.hdr.type_of_loader || + !ramdisk_image || !ramdisk_size) + return; /* No initrd provided by bootloader */ + + initrd_start = 0; + + if (ramdisk_size >= (end_of_lowmem>>1)) { + free_early(ramdisk_image, ramdisk_end); + printk(KERN_ERR "initrd too large to handle, " + "disabling initrd\n"); + return; + } + + printk(KERN_INFO "RAMDISK: %08llx - %08llx\n", ramdisk_image, + ramdisk_end); + + + if (ramdisk_end <= end_of_lowmem) { + /* All in lowmem, easy case */ + /* + * don't need to reserve again, already reserved early + * in i386_start_kernel + */ + initrd_start = ramdisk_image + PAGE_OFFSET; + initrd_end = initrd_start + ramdisk_size; + return; + } + +#ifdef CONFIG_X86_32 + relocate_initrd(); +#else + printk(KERN_ERR "initrd extends beyond end of memory " + "(0x%08llx > 0x%08llx)\ndisabling initrd\n", + ramdisk_end, end_of_lowmem); + initrd_start = 0; +#endif + free_early(ramdisk_image, ramdisk_end); } #else -void __init reserve_initrd(void) +static void __init reserve_initrd(void) { } #endif /* CONFIG_BLK_DEV_INITRD */ -- cgit v1.2.3 From 7dea23ecd17db6e42e19499db70d2fcfa5ca1ee2 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Jun 2008 17:50:06 -0700 Subject: x86: put global variable for 32bit all together those variables are not needed by 64 bit. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 57 +++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 24 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index aa81779db218..98f9199026cd 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -100,6 +100,8 @@ static struct resource bss_resource = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; + +#ifdef CONFIG_X86_32 static struct resource video_ram_resource = { .name = "Video RAM area", .start = 0xa0000, @@ -108,24 +110,47 @@ static struct resource video_ram_resource = { }; /* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1}; /* common cpu data for all cpus */ -struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1}; EXPORT_SYMBOL(boot_cpu_data); +static void set_mca_bus(int x) +{ +#ifdef CONFIG_MCA + MCA_bus = x; +#endif +} unsigned int def_to_bigsmp; -#ifndef CONFIG_X86_PAE -unsigned long mmu_cr4_features; -#else -unsigned long mmu_cr4_features = X86_CR4_PAE; -#endif - /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; unsigned int machine_submodel_id; unsigned int BIOS_revision; +struct apm_info apm_info; +EXPORT_SYMBOL(apm_info); + +#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \ + defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) +struct ist_info ist_info; +EXPORT_SYMBOL(ist_info); +#else +struct ist_info ist_info; +#endif + +#else +struct cpuinfo_x86 boot_cpu_data __read_mostly; +EXPORT_SYMBOL(boot_cpu_data); +#endif + + +#if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64) +unsigned long mmu_cr4_features; +#else +unsigned long mmu_cr4_features = X86_CR4_PAE; +#endif + /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -140,15 +165,8 @@ char dmi_alloc_data[DMI_MAX_DATA]; */ struct screen_info screen_info; EXPORT_SYMBOL(screen_info); -struct apm_info apm_info; -EXPORT_SYMBOL(apm_info); struct edid_info edid_info; EXPORT_SYMBOL_GPL(edid_info); -struct ist_info ist_info; -#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \ - defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) -EXPORT_SYMBOL(ist_info); -#endif extern int root_mountflags; @@ -303,15 +321,6 @@ static void __init reserve_initrd(void) } #endif /* CONFIG_BLK_DEV_INITRD */ -#ifdef CONFIG_MCA -static void set_mca_bus(int x) -{ - MCA_bus = x; -} -#else -static void set_mca_bus(int x) { } -#endif - /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures -- cgit v1.2.3 From 46d671b525102ae005dc5e8389ca67c86ae012b1 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 25 Jun 2008 17:51:29 -0700 Subject: x86: add extra includes for 64bit support Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/setup_32.c | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'arch/x86/kernel/setup_32.c') diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 98f9199026cd..0b69483b0c3d 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -45,31 +45,75 @@ #include #include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + #include