Merge branch 'x86-trampoline-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / x86 / kernel / setup.c
index a59f6a6..95a3274 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/apm_bios.h>
 #include <linux/initrd.h>
 #include <linux/bootmem.h>
+#include <linux/memblock.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
 #include <linux/mca.h>
@@ -301,7 +302,7 @@ static inline void init_gbpages(void)
 static void __init reserve_brk(void)
 {
        if (_brk_end > _brk_start)
-               reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
+               memblock_x86_reserve_range(__pa(_brk_start), __pa(_brk_end), "BRK");
 
        /* Mark brk area as locked down and no longer taking any
           new allocations */
@@ -323,17 +324,16 @@ static void __init relocate_initrd(void)
        char *p, *q;
 
        /* We need to move the initrd down into lowmem */
-       ramdisk_here = find_e820_area(0, end_of_lowmem, area_size,
+       ramdisk_here = memblock_find_in_range(0, end_of_lowmem, area_size,
                                         PAGE_SIZE);
 
-       if (ramdisk_here == -1ULL)
+       if (ramdisk_here == MEMBLOCK_ERROR)
                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 + area_size,
-                        "NEW RAMDISK");
+       memblock_x86_reserve_range(ramdisk_here, ramdisk_here + area_size, "NEW RAMDISK");
        initrd_start = ramdisk_here + PAGE_OFFSET;
        initrd_end   = initrd_start + ramdisk_size;
        printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n",
@@ -389,7 +389,7 @@ static void __init reserve_initrd(void)
        initrd_start = 0;
 
        if (ramdisk_size >= (end_of_lowmem>>1)) {
-               free_early(ramdisk_image, ramdisk_end);
+               memblock_x86_free_range(ramdisk_image, ramdisk_end);
                printk(KERN_ERR "initrd too large to handle, "
                       "disabling initrd\n");
                return;
@@ -412,7 +412,7 @@ static void __init reserve_initrd(void)
 
        relocate_initrd();
 
-       free_early(ramdisk_image, ramdisk_end);
+       memblock_x86_free_range(ramdisk_image, ramdisk_end);
 }
 #else
 static void __init reserve_initrd(void)
@@ -468,7 +468,7 @@ static void __init e820_reserve_setup_data(void)
        e820_print_map("reserve setup_data");
 }
 
-static void __init reserve_early_setup_data(void)
+static void __init memblock_x86_reserve_range_setup_data(void)
 {
        struct setup_data *data;
        u64 pa_data;
@@ -480,7 +480,7 @@ static void __init reserve_early_setup_data(void)
        while (pa_data) {
                data = early_memremap(pa_data, sizeof(*data));
                sprintf(buf, "setup data %x", data->type);
-               reserve_early(pa_data, pa_data+sizeof(*data)+data->len, buf);
+               memblock_x86_reserve_range(pa_data, pa_data+sizeof(*data)+data->len, buf);
                pa_data = data->next;
                early_iounmap(data, sizeof(*data));
        }
@@ -501,6 +501,7 @@ static inline unsigned long long get_total_mem(void)
        return total << PAGE_SHIFT;
 }
 
+#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
 static void __init reserve_crashkernel(void)
 {
        unsigned long long total_mem;
@@ -518,23 +519,27 @@ static void __init reserve_crashkernel(void)
        if (crash_base <= 0) {
                const unsigned long long alignment = 16<<20;    /* 16M */
 
-               crash_base = find_e820_area(alignment, ULONG_MAX, crash_size,
-                                alignment);
-               if (crash_base == -1ULL) {
+               /*
+                *  kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
+                */
+               crash_base = memblock_find_in_range(alignment,
+                              DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
+
+               if (crash_base == MEMBLOCK_ERROR) {
                        pr_info("crashkernel reservation failed - No suitable area found.\n");
                        return;
                }
        } else {
                unsigned long long start;
 
-               start = find_e820_area(crash_base, ULONG_MAX, crash_size,
-                                1<<20);
+               start = memblock_find_in_range(crash_base,
+                                crash_base + crash_size, crash_size, 1<<20);
                if (start != crash_base) {
                        pr_info("crashkernel reservation failed - memory is in use.\n");
                        return;
                }
        }
-       reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL");
+       memblock_x86_reserve_range(crash_base, crash_base + crash_size, "CRASH KERNEL");
 
        printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
                        "for crashkernel (System RAM: %ldMB)\n",
@@ -614,7 +619,7 @@ static __init void reserve_ibft_region(void)
        addr = find_ibft_region(&size);
 
        if (size)
-               reserve_early_overlap_ok(addr, addr + size, "ibft");
+               memblock_x86_reserve_range(addr, addr + size, "* ibft");
 }
 
 static unsigned reserve_low = CONFIG_X86_RESERVE_LOW << 10;
@@ -664,6 +669,15 @@ static int __init parse_reservelow(char *p)
 
 early_param("reservelow", parse_reservelow);
 
+static u64 __init get_max_mapped(void)
+{
+       u64 end = max_pfn_mapped;
+
+       end <<= PAGE_SHIFT;
+
+       return end;
+}
+
 /*
  * 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
@@ -686,6 +700,17 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_X86_32
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        visws_early_detect();
+
+       /*
+        * copy kernel address range established so far and switch
+        * to the proper swapper page table
+        */
+       clone_pgd_range(swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       initial_page_table + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
+
+       load_cr3(swapper_pg_dir);
+       __flush_tlb_all();
 #else
        printk(KERN_INFO "Command line: %s\n", boot_command_line);
 #endif
@@ -738,7 +763,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
         4)) {
                efi_enabled = 1;
-               efi_reserve_early();
+               efi_memblock_x86_reserve_range();
        }
 #endif
 
@@ -795,7 +820,7 @@ void __init setup_arch(char **cmdline_p)
        x86_report_nx();
 
        /* after early param, so could get panic from serial */
-       reserve_early_setup_data();
+       memblock_x86_reserve_range_setup_data();
 
        if (acpi_mps_check()) {
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -848,8 +873,6 @@ void __init setup_arch(char **cmdline_p)
         */
        max_pfn = e820_end_of_ram_pfn();
 
-       /* 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))
@@ -871,18 +894,8 @@ void __init setup_arch(char **cmdline_p)
                max_low_pfn = max_pfn;
 
        high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
-       max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
-#endif
-
-#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
-       setup_bios_corruption_check();
 #endif
 
-       printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
-                       max_pfn_mapped<<PAGE_SHIFT);
-
-       reserve_brk();
-
        /*
         * Find and reserve possible boot-time SMP configuration:
         */
@@ -890,6 +903,26 @@ void __init setup_arch(char **cmdline_p)
 
        reserve_ibft_region();
 
+       /*
+        * Need to conclude brk, before memblock_x86_fill()
+        *  it could use memblock_find_in_range, could overlap with
+        *  brk area.
+        */
+       reserve_brk();
+
+       memblock.current_limit = get_max_mapped();
+       memblock_x86_fill();
+
+       /* preallocate 4k for mptable mpc */
+       early_reserve_e820_mpc_new();
+
+#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
+       setup_bios_corruption_check();
+#endif
+
+       printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n",
+                       max_pfn_mapped<<PAGE_SHIFT);
+
        reserve_trampoline_memory();
 
 #ifdef CONFIG_ACPI_SLEEP
@@ -913,6 +946,7 @@ void __init setup_arch(char **cmdline_p)
                max_low_pfn = max_pfn;
        }
 #endif
+       memblock.current_limit = get_max_mapped();
 
        /*
         * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
@@ -951,10 +985,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        initmem_init(0, max_pfn, acpi, k8);
-#ifndef CONFIG_NO_BOOTMEM
-       early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
-#endif
-
+       memblock_find_dma_reserve();
        dma32_reserve_bootmem();
 
 #ifdef CONFIG_KVM_CLOCK
@@ -965,7 +996,12 @@ void __init setup_arch(char **cmdline_p)
        paging_init();
        x86_init.paging.pagetable_setup_done(swapper_pg_dir);
 
-       setup_trampoline_page_table();
+#ifdef CONFIG_X86_32
+       /* sync back kernel address range */
+       clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
+                       swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
+                       KERNEL_PGD_PTRS);
+#endif
 
        tboot_probe();